diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-05-17 21:09:03 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-05-17 21:09:03 +0300 |
commit | d39fdda20b10028e183facaaebb76af438759762 (patch) | |
tree | 7732de84cc3a5a28781bba207234fe4100bfc2e9 | |
parent | 94feea22e6ecc1a45dfc578606cad454507f6ab2 (diff) | |
parent | 9c5682af879021ed530dca0cfd6126f3031cc762 (diff) |
Merge branch 'blender2.8' into temp-unified-collectionstemp-unified-collections
152 files changed, 4616 insertions, 3995 deletions
diff --git a/release/datafiles/studiolights/camera/camera01.hdr b/release/datafiles/studiolights/camera/camera01.hdr Binary files differnew file mode 100644 index 00000000000..341b15524c5 --- /dev/null +++ b/release/datafiles/studiolights/camera/camera01.hdr diff --git a/release/datafiles/studiolights/camera/camera02.jpg b/release/datafiles/studiolights/camera/camera02.jpg Binary files differnew file mode 100644 index 00000000000..37be86325df --- /dev/null +++ b/release/datafiles/studiolights/camera/camera02.jpg diff --git a/release/datafiles/studiolights/sl01.jpg b/release/datafiles/studiolights/sl01.jpg Binary files differdeleted file mode 100644 index cd007bade68..00000000000 --- a/release/datafiles/studiolights/sl01.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/sl02.jpg b/release/datafiles/studiolights/world/sl02.jpg Binary files differindex 1c9ce99a0d8..1c9ce99a0d8 100644 --- a/release/datafiles/studiolights/sl02.jpg +++ b/release/datafiles/studiolights/world/sl02.jpg diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index f48cf69d1c9..a9d766b29e2 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2338,7 +2338,7 @@ class WM_OT_tool_set_by_name(Operator): def execute(self, context): from bl_ui.space_toolsystem_common import activate_by_name - if activate_by_name(context, self.name): + if activate_by_name(context, context.space_data.type, self.name): return {'FINISHED'} else: self.report({'WARNING'}, f"Tool {self.name!r} not found.") diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 251f32a37e4..f0526fc0271 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -318,8 +318,8 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel): sub.active = ob.use_dupli_faces_scale sub.prop(ob, "dupli_faces_scale", text="Inherit Scale") - elif ob.dupli_type == 'GROUP': - layout.prop(ob, "dupli_group", text="Group") + elif ob.dupli_type == 'COLLECTION': + layout.prop(ob, "dupli_group", text="Collection") from .properties_animviz import ( diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index e6d5d9bf837..93de404245f 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -431,25 +431,13 @@ class RENDER_PT_stereoscopy(RenderButtonsPanel, Panel): row.prop(rv, "camera_suffix", text="") -class RENDER_PT_clay_layer_settings(RenderButtonsPanel, Panel): - bl_label = "Clay Layer Settings" +class RENDER_PT_clay_settings(RenderButtonsPanel, Panel): + bl_label = "Clay Settings" COMPAT_ENGINES = {'BLENDER_CLAY'} def draw(self, context): layout = self.layout - props = context.scene.layer_properties['BLENDER_CLAY'] - - col = layout.column() - col.prop(props, "ssao_samples") - - -class RENDER_PT_clay_collection_settings(RenderButtonsPanel, Panel): - bl_label = "Clay Collection Settings" - COMPAT_ENGINES = {'BLENDER_CLAY'} - - def draw(self, context): - layout = self.layout - props = context.scene.collection_properties['BLENDER_CLAY'] + props = context.scene.display col = layout.column() col.template_icon_view(props, "matcap_icon") @@ -457,11 +445,12 @@ class RENDER_PT_clay_collection_settings(RenderButtonsPanel, Panel): col.prop(props, "matcap_hue") col.prop(props, "matcap_saturation") col.prop(props, "matcap_value") - col.prop(props, "ssao_factor_cavity") - col.prop(props, "ssao_factor_edge") - col.prop(props, "ssao_distance") - col.prop(props, "ssao_attenuation") - col.prop(props, "hair_brightness_randomness") + col.prop(props, "matcap_ssao_samples") + col.prop(props, "matcap_ssao_factor_cavity") + col.prop(props, "matcap_ssao_factor_edge") + col.prop(props, "matcap_ssao_distance") + col.prop(props, "matcap_ssao_attenuation") + col.prop(props, "matcap_hair_brightness_randomness") class RENDER_PT_eevee_ambient_occlusion(RenderButtonsPanel, Panel): @@ -475,13 +464,13 @@ class RENDER_PT_eevee_ambient_occlusion(RenderButtonsPanel, Panel): def draw_header(self, context): scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee self.layout.prop(props, "gtao_enable", text="") def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee layout.active = props.gtao_enable col = layout.column() @@ -503,13 +492,13 @@ class RENDER_PT_eevee_motion_blur(RenderButtonsPanel, Panel): def draw_header(self, context): scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee self.layout.prop(props, "motion_blur_enable", text="") def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee layout.active = props.motion_blur_enable col = layout.column() @@ -528,13 +517,13 @@ class RENDER_PT_eevee_depth_of_field(RenderButtonsPanel, Panel): def draw_header(self, context): scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee self.layout.prop(props, "dof_enable", text="") def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee layout.active = props.dof_enable col = layout.column() @@ -553,13 +542,13 @@ class RENDER_PT_eevee_bloom(RenderButtonsPanel, Panel): def draw_header(self, context): scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee self.layout.prop(props, "bloom_enable", text="") def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee layout.active = props.bloom_enable col = layout.column() @@ -582,13 +571,13 @@ class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel): def draw_header(self, context): scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee self.layout.prop(props, "volumetric_enable", text="") def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee layout.active = props.volumetric_enable col = layout.column() @@ -615,13 +604,13 @@ class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel): def draw_header(self, context): scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee self.layout.prop(props, "sss_enable", text="") def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee col = layout.column() col.prop(props, "sss_samples") @@ -640,13 +629,13 @@ class RENDER_PT_eevee_screen_space_reflections(RenderButtonsPanel, Panel): def draw_header(self, context): scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee self.layout.prop(props, "ssr_enable", text="") def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee col = layout.column() col.active = props.ssr_enable @@ -671,7 +660,7 @@ class RENDER_PT_eevee_shadows(RenderButtonsPanel, Panel): def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee col = layout.column() col.prop(props, "shadow_method") @@ -692,7 +681,7 @@ class RENDER_PT_eevee_sampling(RenderButtonsPanel, Panel): def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee col = layout.column() col.prop(props, "taa_samples") @@ -712,7 +701,7 @@ class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel): def draw(self, context): layout = self.layout scene = context.scene - props = scene.layer_properties['BLENDER_EEVEE'] + props = scene.eevee col = layout.column() col.prop(props, "gi_diffuse_bounces") @@ -756,8 +745,7 @@ classes = ( RENDER_PT_encoding, RENDER_UL_renderviews, RENDER_PT_stereoscopy, - RENDER_PT_clay_layer_settings, - RENDER_PT_clay_collection_settings, + RENDER_PT_clay_settings, RENDER_PT_eevee_sampling, RENDER_PT_eevee_film, RENDER_PT_eevee_shadows, diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 3c20d92106e..2a59c2c5f79 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -37,17 +37,22 @@ class OUTLINER_HT_header(Header): layout.prop(space, "display_mode", text="") - row = layout.row() - if display_mode in {'OBJECTS', 'COLLECTIONS'}: + row = layout.row(align=True) + if display_mode in {'VIEW_LAYER'}: row.popover(space_type='OUTLINER', region_type='HEADER', panel_type="OUTLINER_PT_filter", text="", icon='FILTER') + elif display_mode in {'LIBRARIES', 'ORPHAN_DATA'}: + row.prop(space, "use_filter_id_type", text="", icon='FILTER') + sub = row.row(align=True) + sub.active = space.use_filter_id_type + sub.prop(space, "filter_id_type", text="", icon_only=True) OUTLINER_MT_editor_menus.draw_collapsible(context, layout) - if display_mode == 'DATABLOCKS': + if space.display_mode == 'DATA_API': layout.separator() row = layout.row(align=True) @@ -86,7 +91,7 @@ class OUTLINER_MT_editor_menus(Menu): layout.menu("OUTLINER_MT_view") - if space.display_mode == 'DATABLOCKS': + if space.display_mode == 'DATA_API': layout.menu("OUTLINER_MT_edit_datablocks") elif space.display_mode == 'ORPHAN_DATA': @@ -101,7 +106,7 @@ class OUTLINER_MT_view(Menu): space = context.space_data - if space.display_mode != 'DATABLOCKS': + if space.display_mode != 'DATA_API': layout.prop(space, "use_sort_alpha") layout.prop(space, "show_restrict_columns") layout.separator() @@ -141,6 +146,18 @@ class OUTLINER_MT_edit_orphan_data(Menu): layout.operator("outliner.orphans_purge") +class OUTLINER_MT_collection_view_layer(Menu): + bl_label = "View Layer" + + def draw(self, context): + layout = self.layout + + space = context.space_data + + layout.operator("outliner.collection_exclude_set", text="Exclude") + layout.operator("outliner.collection_include_set", text="Include") + + class OUTLINER_MT_collection(Menu): bl_label = "Collection" @@ -149,7 +166,7 @@ class OUTLINER_MT_collection(Menu): space = context.space_data - layout.operator("outliner.collection_new", text="New") + layout.operator("outliner.collection_new", text="New").nested = True layout.operator("outliner.collection_duplicate", text="Duplicate") layout.operator("outliner.collection_delete", text="Delete").hierarchy = False layout.operator("outliner.collection_delete", text="Delete Hierarchy").hierarchy = True @@ -162,11 +179,14 @@ class OUTLINER_MT_collection(Menu): layout.separator() layout.operator("outliner.collection_instance", text="Instance to Scene") - if space.display_mode == 'COLLECTIONS' and space.filter_collection != 'SCENE': + if space.display_mode != 'VIEW_LAYER': layout.operator("outliner.collection_link", text="Link to Scene") layout.operator("outliner.id_operation", text="Unlink").type='UNLINK' - # TODO: needed for static override, but not all operators work + if space.display_mode == 'VIEW_LAYER': + layout.separator() + layout.menu("OUTLINER_MT_collection_view_layer") + layout.separator() layout.operator_menu_enum("outliner.id_operation", 'type', text="ID Data") @@ -177,7 +197,7 @@ class OUTLINER_MT_collection_new(Menu): def draw(self, context): layout = self.layout - layout.operator("outliner.collection_new", text="New") + layout.operator("outliner.collection_new", text="New").nested = False class OUTLINER_MT_object(Menu): @@ -189,7 +209,7 @@ class OUTLINER_MT_object(Menu): space = context.space_data layout.operator("outliner.object_operation", text="Delete").type='DELETE' - if space.display_mode != 'COLLECTIONS': + if space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection: layout.operator("outliner.object_operation", text="Delete Hierarchy").type='DELETE_HIERARCHY' layout.separator() @@ -200,11 +220,10 @@ class OUTLINER_MT_object(Menu): layout.separator() - if space.display_mode == 'COLLECTIONS': + if not (space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection): layout.operator("outliner.id_operation", text="Unlink").type='UNLINK' layout.separator() - # TODO: needed for static override, but not all operators work layout.operator_menu_enum("outliner.id_operation", 'type', text="ID Data") @@ -219,20 +238,13 @@ class OUTLINER_PT_filter(Panel): space = context.space_data display_mode = space.display_mode - if display_mode == 'COLLECTIONS': - col = layout.column(align=True) - col.label(text="Collections:") - col.row().prop(space, "filter_collection", expand=True) + layout.prop(space, "use_filter_collection", text="Collections") - layout.separator() + layout.separator() col = layout.column() - if display_mode == 'COLLECTIONS': - col.prop(space, "use_filter_object", text="Objects") - active = space.use_filter_object - else: - col.label("Objects:") - active = True + col.prop(space, "use_filter_object", text="Objects") + active = space.use_filter_object sub = col.column(align=True) sub.active = active @@ -272,6 +284,7 @@ classes = ( OUTLINER_MT_edit_orphan_data, OUTLINER_MT_collection, OUTLINER_MT_collection_new, + OUTLINER_MT_collection_view_layer, OUTLINER_MT_object, OUTLINER_PT_filter, ) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index ed683bcc312..b58bff7cf32 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -253,11 +253,11 @@ class ToolSelectPanelHelper: return None, 0 @staticmethod - def _tool_get_by_name(context, text): + def _tool_get_by_name(context, space_type, text): """ Return the active Python tool definition and index (if in sub-group, else -1). """ - cls = ToolSelectPanelHelper._tool_class_from_space_type(context.space_data.type) + cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) if cls is not None: context_mode = context.mode for item, index in ToolSelectPanelHelper._tools_flatten_with_tool_index(cls.tools_from_context(context)): @@ -556,15 +556,15 @@ class WM_MT_toolsystem_submenu(Menu): continue tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name) - props = layout.operator( + layout.operator( "wm.tool_set_by_name", text=item.text, icon_value=icon_value, ).name = item.text -def activate_by_name(context, text): - item, index = ToolSelectPanelHelper._tool_get_by_name(context, text) +def activate_by_name(context, space_type, text): + item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text) if item is not None: context_mode = context.mode tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 719396ccdd1..69afa0da12e 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -197,38 +197,50 @@ class TOPBAR_HT_lower_bar(Header): object_mode = 'OBJECT' if obj is None else obj.mode - # Pivit & Orientation - row = layout.row(align=True) - row.prop(toolsettings, "transform_pivot_point", text="", icon_only=True) - if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}): - row.prop(toolsettings, "use_transform_pivot_point_align", text="") + # Pivot & Orientation + pivot_point = context.tool_settings.transform_pivot_point + act_pivot_point = bpy.types.ToolSettings.bl_rna.properties['transform_pivot_point'].enum_items[pivot_point] - layout.prop(scene, "transform_orientation", text="") + row = layout.row(align=True) + row.popover( + space_type='TOPBAR', + region_type='HEADER', + panel_type="TOPBAR_PT_pivot_point", + icon=act_pivot_point.icon, + text="" + ) if obj: # Proportional editing if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: row = layout.row(align=True) row.prop(toolsettings, "proportional_edit", icon_only=True) - if toolsettings.proportional_edit != 'DISABLED': - row.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + + sub = row.row(align=True) + sub.enabled = toolsettings.proportional_edit != 'DISABLED' + sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + elif object_mode in {'EDIT', 'PARTICLE_EDIT'}: row = layout.row(align=True) row.prop(toolsettings, "proportional_edit", icon_only=True) - if toolsettings.proportional_edit != 'DISABLED': - row.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + sub = row.row(align=True) + sub.enabled = toolsettings.proportional_edit != 'DISABLED' + sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + elif object_mode == 'OBJECT': row = layout.row(align=True) row.prop(toolsettings, "use_proportional_edit_objects", icon_only=True) - if toolsettings.use_proportional_edit_objects: - row.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + sub = row.row(align=True) + sub.enabled = toolsettings.use_proportional_edit_objects + sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True) else: # Proportional editing if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: row = layout.row(align=True) row.prop(toolsettings, "proportional_edit", icon_only=True) - if toolsettings.proportional_edit != 'DISABLED': - row.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + sub = row.row(align=True) + sub.enabled = toolsettings.proportional_edit != 'DISABLED' + sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True) # Snap show_snap = False @@ -249,28 +261,22 @@ class TOPBAR_HT_lower_bar(Header): if show_snap: snap_element = toolsettings.snap_element + act_snap_element = bpy.types.ToolSettings.bl_rna.properties['snap_element'].enum_items[snap_element] + row = layout.row(align=True) row.prop(toolsettings, "use_snap", text="") - row.prop(toolsettings, "snap_element", icon_only=True) - if snap_element == 'INCREMENT': - row.prop(toolsettings, "use_snap_grid_absolute", text="") - else: - row.prop(toolsettings, "snap_target", text="") - if obj: - if object_mode == 'EDIT': - row.prop(toolsettings, "use_snap_self", text="") - if object_mode in {'OBJECT', 'POSE', 'EDIT'} and snap_element != 'VOLUME': - row.prop(toolsettings, "use_snap_align_rotation", text="") - - if snap_element == 'VOLUME': - row.prop(toolsettings, "use_snap_peel_object", text="") - elif snap_element == 'FACE': - row.prop(toolsettings, "use_snap_project", text="") - - # AutoMerge editing - if obj: - if (object_mode == 'EDIT' and obj.type == 'MESH'): - layout.prop(toolsettings, "use_mesh_automerge", text="", icon='AUTOMERGE_ON') + + sub = row.row(align=True) + sub.enabled = toolsettings.use_snap + sub.popover( + space_type='TOPBAR', + region_type='HEADER', + panel_type="TOPBAR_PT_snapping", + icon=act_snap_element.icon, + text="" + ) + + layout.prop(scene, "transform_orientation", text="") # Command Settings (redo) op = context.active_operator @@ -331,6 +337,73 @@ class _draw_left_context_mode: UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") +class TOPBAR_PT_pivot_point(Panel): + bl_space_type = 'TOPBAR' + bl_region_type = 'HEADER' + bl_label = "Pivot Point" + + def draw(self, context): + toolsettings = context.tool_settings + obj = context.active_object + mode = context.mode + + layout = self.layout + col = layout.column() + col.label(text="Pivot Point") + col.prop(toolsettings, "transform_pivot_point", expand=True) + + col.separator() + + if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}): + col.prop( + toolsettings, + "use_transform_pivot_point_align", + text="Center Points Only") + + +class TOPBAR_PT_snapping(Panel): + bl_space_type = 'TOPBAR' + bl_region_type = 'HEADER' + bl_label = "Snapping" + + def draw(self, context): + toolsettings = context.tool_settings + snap_element = toolsettings.snap_element + obj = context.active_object + mode = context.mode + object_mode = 'OBJECT' if obj is None else obj.mode + + layout = self.layout + col = layout.column() + col.label(text="Snapping") + col.prop(toolsettings, "snap_element", expand=True) + + col.separator() + + if snap_element == 'INCREMENT': + col.prop(toolsettings, "use_snap_grid_absolute") + else: + col.label(text="Target") + row = col.row(align=True) + row.prop(toolsettings, "snap_target", expand=True) + + if obj: + if object_mode == 'EDIT': + col.prop(toolsettings, "use_snap_self") + if object_mode in {'OBJECT', 'POSE', 'EDIT'} and snap_element != 'VOLUME': + col.prop(toolsettings, "use_snap_align_rotation", text="Align Rotation") + + if snap_element == 'VOLUME': + col.prop(toolsettings, "use_snap_peel_object") + elif snap_element == 'FACE': + col.prop(toolsettings, "use_snap_project", text="Project Elements") + + # Auto-Merge Editing + if obj: + if (object_mode == 'EDIT' and obj.type == 'MESH'): + col.prop(toolsettings, "use_mesh_automerge", icon='AUTOMERGE_ON') + + class INFO_MT_editor_menus(Menu): bl_idname = "INFO_MT_editor_menus" bl_label = "" @@ -597,6 +670,8 @@ class INFO_MT_help(Menu): classes = ( TOPBAR_HT_upper_bar, TOPBAR_HT_lower_bar, + TOPBAR_PT_pivot_point, + TOPBAR_PT_snapping, INFO_MT_editor_menus, INFO_MT_file, INFO_MT_file_import, diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 080e472cea5..f20e9021e28 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3510,14 +3510,17 @@ class VIEW3D_PT_shading(Panel): col.row().prop(shading, "light", expand=True) if shading.light == 'STUDIO': col.row().template_icon_view(shading, "studio_light") + if shading.studio_light_orientation == 'WORLD': + col.row().prop(shading, "studiolight_rot_z") col.separator() - row = col.row() - row.prop(shading, "show_shadows") - sub = row.row() - sub.active = shading.show_shadows - sub.prop(shading, "shadow_intensity", text="") + if not(shading.light == 'STUDIO' and shading.studio_light_orientation == 'WORLD'): + row = col.row() + row.prop(shading, "show_shadows") + sub = row.row() + sub.active = shading.show_shadows + sub.prop(shading, "shadow_intensity", text="") col.prop(shading, "show_object_outline") diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 0d283d39af7..591180f08b4 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -209,7 +209,7 @@ shader_node_categories = [ NodeItem("ShaderNodeEmission", poll=object_eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeBsdfHair", poll=object_cycles_shader_nodes_poll), NodeItem("ShaderNodeBackground", poll=world_shader_nodes_poll), - NodeItem("ShaderNodeAmbientOcclusion", poll=object_cycles_shader_nodes_poll), + NodeItem("ShaderNodeAmbientOcclusion", poll=object_eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeHoldout", poll=object_cycles_shader_nodes_poll), NodeItem("ShaderNodeVolumeAbsorption", poll=eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll), @@ -253,6 +253,7 @@ shader_node_categories = [ NodeItem("ShaderNodeMath"), NodeItem("ShaderNodeValToRGB"), NodeItem("ShaderNodeRGBToBW"), + NodeItem("ShaderNodeShaderToRGB", poll=object_eevee_shader_nodes_poll), NodeItem("ShaderNodeVectorMath"), NodeItem("ShaderNodeSeparateRGB"), NodeItem("ShaderNodeCombineRGB"), diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc index b31a185e39b..e7cc474e2e8 100644 --- a/source/blender/alembic/intern/abc_hair.cc +++ b/source/blender/alembic/intern/abc_hair.cc @@ -73,7 +73,7 @@ void AbcHairWriter::do_write() ParticleSystemModifierData *psmd = psys_get_modifier(m_object, m_psys); - if (!psmd->dm_final) { + if (!psmd->mesh_final) { return; } diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 725ef65b511..dba3f6938c3 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -57,8 +57,6 @@ struct Scene; struct ViewLayer; struct WorkSpace; -void BKE_layer_exit(void); - struct ViewLayer *BKE_view_layer_default_view(const struct Scene *scene); struct ViewLayer *BKE_view_layer_default_render(const struct Scene *scene); struct ViewLayer *BKE_view_layer_from_workspace_get(const struct Scene *scene, const struct WorkSpace *workspace); @@ -84,6 +82,7 @@ void BKE_view_layer_copy_data( const int flag); struct LayerCollection *BKE_layer_collection_get_active(struct ViewLayer *view_layer); +bool BKE_layer_collection_activate(struct ViewLayer *view_layer, struct LayerCollection *lc); struct LayerCollection *BKE_layer_collection_activate_parent(struct ViewLayer *view_layer, struct LayerCollection *lc); int BKE_layer_collection_count(struct ViewLayer *view_layer); @@ -110,37 +109,6 @@ void BKE_override_view_layer_int_add(struct ViewLayer *view_layer, int id_type, void BKE_override_layer_collection_boolean_add(struct LayerCollection *layer_collection, int id_type, const char *data_path, const bool value); -/* engine settings */ -typedef void (*EngineSettingsCB)(struct RenderEngine *engine, struct IDProperty *props); - -struct IDProperty *BKE_layer_collection_engine_scene_get(struct Scene *scene, const char *engine_name); -void BKE_layer_collection_engine_settings_callback_register(struct Main *bmain, const char *engine_name, EngineSettingsCB func); -void BKE_layer_collection_engine_settings_callback_free(void); -void BKE_layer_collection_engine_settings_create(struct IDProperty *root); -void BKE_layer_collection_engine_settings_validate_scene(struct Scene *scene); - -struct IDProperty *BKE_view_layer_engine_evaluated_get(struct ViewLayer *view_layer, const char *engine_name); -struct IDProperty *BKE_view_layer_engine_scene_get(struct Scene *scene, const char *engine_name); -void BKE_view_layer_engine_settings_callback_register(struct Main *bmain, const char *engine_name, EngineSettingsCB func); -void BKE_view_layer_engine_settings_callback_free(void); -void BKE_view_layer_engine_settings_validate_scene(struct Scene *scene); -void BKE_view_layer_engine_settings_create(struct IDProperty *root); - -void BKE_collection_engine_property_add_float(struct IDProperty *props, const char *name, float value); -void BKE_collection_engine_property_add_float_array( - struct IDProperty *props, const char *name, const float *values, const int array_length); -void BKE_collection_engine_property_add_int(struct IDProperty *props, const char *name, int value); -void BKE_collection_engine_property_add_bool(struct IDProperty *props, const char *name, bool value); - -int BKE_collection_engine_property_value_get_int(struct IDProperty *props, const char *name); -float BKE_collection_engine_property_value_get_float(struct IDProperty *props, const char *name); -const float *BKE_collection_engine_property_value_get_float_array(struct IDProperty *props, const char *name); -bool BKE_collection_engine_property_value_get_bool(struct IDProperty *props, const char *name); -void BKE_collection_engine_property_value_set_int(struct IDProperty *props, const char *name, int value); -void BKE_collection_engine_property_value_set_float(struct IDProperty *props, const char *name, float value); -void BKE_collection_engine_property_value_set_float_array(struct IDProperty *props, const char *name, const float *values); -void BKE_collection_engine_property_value_set_bool(struct IDProperty *props, const char *name, bool value); - /* evaluation */ void BKE_layer_eval_view_layer( diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index dfc3b15403d..25b91be3791 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -31,6 +31,9 @@ * \ingroup bke */ +/* defines BLI_INLINE */ +#include "BLI_utildefines.h" + struct ID; struct BMeshCreateParams; struct BMeshFromMeshParams; @@ -459,6 +462,7 @@ void BKE_mesh_calc_relative_deform( /* *** mesh_validate.c *** */ int BKE_mesh_validate(struct Mesh *me, const int do_verbose, const int cddata_check_mask); +bool BKE_mesh_is_valid(struct Mesh *me); int BKE_mesh_validate_material_indices(struct Mesh *me); bool BKE_mesh_validate_arrays( @@ -502,6 +506,20 @@ enum { void BKE_mesh_batch_cache_dirty(struct Mesh *me, int mode); void BKE_mesh_batch_cache_free(struct Mesh *me); + +/* Inlines */ + +/* This is a copy of DM_origindex_mface_mpoly(). + * Instead of -1 that function uses ORIGINDEX_NONE as defined in BKE_customdata.h, + * but I don't want to force every user of BKE_mesh.h to also include that file. + * ~~ Sybren */ +BLI_INLINE int BKE_mesh_origindex_mface_mpoly( + const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i) +{ + const int j = index_mf_to_mpoly[i]; + return (j != -1) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : -1; +} + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 0ca6aa14cd8..ab00b8174b5 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -498,6 +498,10 @@ void modifier_deformVerts( struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh, float (*vertexCos)[3], int numVerts); +void modifier_deformVerts_ensure_normals( + struct ModifierData *md, const struct ModifierEvalContext *ctx, + struct Mesh *mesh, float (*vertexCos)[3], int numVerts); + void modifier_deformMatrices( struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts); @@ -516,6 +520,10 @@ struct Mesh *modifier_applyModifier( struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh); +struct Mesh *modifier_applyModifier_ensure_normals( + struct ModifierData *md, const struct ModifierEvalContext *ctx, + struct Mesh *mesh); + struct Mesh *modifier_applyModifierEM( struct ModifierData *md, const struct ModifierEvalContext *ctx, struct BMEditMesh *editData, struct Mesh *mesh); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index d85f4095eb9..f3cbcd7b99f 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -714,6 +714,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, c #define SH_NODE_MIX_RGB 103 #define SH_NODE_VALTORGB 104 #define SH_NODE_RGBTOBW 105 +#define SH_NODE_SHADERTORGB 106 //#define SH_NODE_TEXTURE 106 #define SH_NODE_NORMAL 107 //#define SH_NODE_GEOMETRY 108 diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 097532ff2c3..b6a87ae333e 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -137,7 +137,7 @@ typedef struct ParticleCacheKey { typedef struct ParticleThreadContext { /* shared */ struct ParticleSimulationData sim; - struct DerivedMesh *dm; + struct Mesh *mesh; struct Material *ma; /* distribution */ @@ -413,34 +413,34 @@ void psys_free_particles(struct ParticleSystem *psys); void psys_free_children(struct ParticleSystem *psys); void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, bool velocity); -void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]); -void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); -void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); -void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); +void psys_vec_rot_to_face(struct Mesh *mesh, struct ParticleData *pa, float vec[3]); +void psys_mat_hair_to_object(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4]); +void psys_mat_hair_to_global(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4]); +void psys_mat_hair_to_orco(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4]); float psys_get_dietime_from_cache(struct PointCache *cache, int index); void psys_free_pdd(struct ParticleSystem *psys); -float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup); +float *psys_cache_vgroup(struct Mesh *mesh, struct ParticleSystem *psys, int vgroup); void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra); void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3]); -float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values); +float psys_particle_value_from_verts(struct Mesh *mesh, short from, struct ParticleData *pa, float *values); void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time); /* BLI_bvhtree_ray_cast callback */ void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit); -void psys_particle_on_dm(struct DerivedMesh *dm_final, int from, int index, int index_dmcache, +void psys_particle_on_dm(struct Mesh *mesh_final, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3]); /* particle_system.c */ void distribute_particles(struct ParticleSimulationData *sim, int from); void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa); -void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm_final, struct DerivedMesh *dm_deformed, struct ParticleSystem *psys); -int psys_particle_dm_face_lookup(struct DerivedMesh *dm_final, struct DerivedMesh *dm_deformed, int findex, const float fw[4], struct LinkNode **poly_nodes); +void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_deformed, struct ParticleSystem *psys); +int psys_particle_dm_face_lookup(struct Mesh *mesh_final, struct Mesh *mesh_deformed, int findex, const float fw[4], struct LinkNode **poly_nodes); void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra); diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h index c65e9050157..33c2af668b2 100644 --- a/source/blender/blenkernel/BKE_studiolight.h +++ b/source/blender/blenkernel/BKE_studiolight.h @@ -38,6 +38,11 @@ #include "DNA_space_types.h" +/* + * These defines are the indexes in the StudioLight.diffuse_light + * X_POS means the light that is traveling towards the positive X + * So Light direction. + */ #define STUDIOLIGHT_X_POS 0 #define STUDIOLIGHT_X_NEG 1 #define STUDIOLIGHT_Y_POS 2 @@ -47,8 +52,11 @@ enum StudioLightFlag { - STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED = (1 << 0), - STUDIOLIGHT_EXTERNAL_FILE = (1 << 1), + STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED = (1 << 0), + STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED = (1 << 1), + STUDIOLIGHT_EXTERNAL_FILE = (1 << 2), + STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 3), + STUDIOLIGHT_ORIENTATION_WORLD = (1 << 4), } StudioLightFlag; typedef struct StudioLight @@ -60,6 +68,7 @@ typedef struct StudioLight int icon_id; int index; float diffuse_light[6][3]; + float light_direction[3]; } StudioLight; void BKE_studiolight_init(void); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 769c109cc31..abbfa4b7ff1 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -84,8 +84,10 @@ #ifdef USE_MODIFIER_VALIDATE # define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true))) +# define ASSERT_IS_VALID_MESH(mesh) (BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true))) #else # define ASSERT_IS_VALID_DM(dm) +# define ASSERT_IS_VALID_MESH(mesh) #endif @@ -95,6 +97,8 @@ static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER; static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob); static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid); +static void mesh_init_origspace(Mesh *mesh); + /* -------------------------------------------------------------------- */ @@ -745,6 +749,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask, bool CustomData_copy(&dm->loopData, &tmp.ldata, mask, alloctype, totloop); CustomData_copy(&dm->polyData, &tmp.pdata, mask, alloctype, totpoly); tmp.cd_flag = dm->cd_flag; + tmp.runtime.deformed_only = dm->deformedOnly; if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) { KeyBlock *kb; @@ -891,6 +896,20 @@ void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask) #endif } +static void mesh_set_only_copy(Mesh *mesh, CustomDataMask mask) +{ + CustomData_set_only_copy(&mesh->vdata, mask); + CustomData_set_only_copy(&mesh->edata, mask); + CustomData_set_only_copy(&mesh->fdata, mask); + /* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with + * weight paint mode when there are modifiers applied, needs further investigation, + * see replies to r50969, Campbell */ +#if 0 + CustomData_set_only_copy(&mesh->ldata, mask); + CustomData_set_only_copy(&mesh->pdata, mask); +#endif +} + void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer) { CustomData_add_layer(&dm->vertData, type, alloctype, layer, dm->numVertData); @@ -1265,6 +1284,30 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int lay return dm; } +static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer) +{ + Mesh *mesh; + float (*orco)[3]; + int free; + + if (em) { + mesh = BKE_bmesh_to_mesh_nomain(em->bm, &(struct BMeshToMeshParams){0}); + } + else { + BKE_id_copy_ex(NULL, &me->id, (ID**)&mesh, + LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_DEG_TAG, false); + } + + orco = get_orco_coords_dm(ob, em, layer, &free); + + if (orco) { + BKE_mesh_apply_vert_coords(mesh, orco); + if (free) MEM_freeN(orco); + } + + return mesh; +} + static void add_orco_dm( Object *ob, BMEditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer) @@ -1303,6 +1346,48 @@ static void add_orco_dm( } } +static void add_orco_mesh( + Object *ob, BMEditMesh *em, Mesh *mesh, + Mesh *orco_mesh, int layer) +{ + float (*orco)[3], (*layerorco)[3]; + int totvert, free; + + totvert = mesh->totvert; + + if (orco_mesh) { + free = 1; + + if (orco_mesh->totvert == totvert) { + orco = BKE_mesh_vertexCos_get(orco_mesh, NULL); + } + else { + orco = BKE_mesh_vertexCos_get(mesh, NULL); + } + } + else { + /* TODO(sybren): totvert should potentially change here, as ob->data + * or em may have a different number of vertices than dm. */ + orco = get_orco_coords_dm(ob, em, layer, &free); + } + + if (orco) { + if (layer == CD_ORCO) { + BKE_mesh_orco_verts_transform(ob->data, orco, totvert, 0); + } + + if (!(layerorco = CustomData_get_layer(&mesh->vdata, layer))) { + CustomData_add_layer(&mesh->vdata, layer, CD_CALLOC, NULL, mesh->totvert); + BKE_mesh_update_customdata_pointers(mesh, false); + + layerorco = CustomData_get_layer(&mesh->vdata, layer); + } + + memcpy(layerorco, orco, sizeof(float) * 3 * totvert); + if (free) MEM_freeN(orco); + } +} + /* weight paint colors */ /* Something of a hack, at the moment deal with weightpaint @@ -1528,6 +1613,81 @@ static void calc_weightpaint_vert_array( } } +static void calc_weightpaint_vert_array_mesh( + Object *ob, Mesh *mesh, int const draw_flag, DMWeightColorInfo *dm_wcinfo, + unsigned char (*r_wtcol_v)[4]) +{ + BMEditMesh *em = BKE_editmesh_from_object(ob); + const int numVerts = mesh->totvert; + + if ((ob->actdef != 0) && + (CustomData_has_layer(em ? &em->bm->vdata : &mesh->vdata, CD_MDEFORMVERT))) + { + unsigned char (*wc)[4] = r_wtcol_v; + unsigned int i; + + /* variables for multipaint */ + const int defbase_tot = BLI_listbase_count(&ob->defbase); + const int defbase_act = ob->actdef - 1; + + int defbase_sel_tot = 0; + bool *defbase_sel = NULL; + + if (draw_flag & CALC_WP_MULTIPAINT) { + defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_sel_tot); + + if (defbase_sel_tot > 1 && (draw_flag & CALC_WP_MIRROR_X)) { + BKE_object_defgroup_mirror_selection(ob, defbase_tot, defbase_sel, defbase_sel, &defbase_sel_tot); + } + } + + /* editmesh won't have deform verts unless modifiers require it, + * avoid having to create an array of deform-verts only for drawing + * by reading from the bmesh directly. */ + if (em) { + BMIter iter; + BMVert *eve; + const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); + BLI_assert(cd_dvert_offset != -1); + + BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) { + const MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); + calc_weightpaint_vert_color( + (unsigned char *)wc, dv, dm_wcinfo, + defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag); + wc++; + } + } + else { + const MDeformVert *dv = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); + for (i = numVerts; i != 0; i--, wc++, dv++) { + calc_weightpaint_vert_color( + (unsigned char *)wc, dv, dm_wcinfo, + defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag); + } + } + + if (defbase_sel) { + MEM_freeN(defbase_sel); + } + } + else { + unsigned char col[4]; + if ((ob->actdef == 0) && !BLI_listbase_is_empty(&ob->defbase)) { + /* color-code for missing data (full brightness isn't easy on the eye). */ + ARRAY_SET_ITEMS(col, 0xa0, 0, 0xa0, 0xff); + } + else if (draw_flag & (CALC_WP_GROUP_USER_ACTIVE | CALC_WP_GROUP_USER_ALL)) { + copy_v3_v3_char((char *)col, dm_wcinfo->alert_color); + col[3] = 255; + } + else { + weightpaint_color(col, dm_wcinfo, 0.0f); + } + copy_vn_i((int *)r_wtcol_v, numVerts, *((int *)col)); + } +} + /** return an array of vertex weight colors from given weights, caller must free. * * \note that we could save some memory and allocate RGB only but then we'd need to @@ -1620,6 +1780,80 @@ void DM_update_weight_mcol( } } +static void mesh_update_weight_mcol( + Object *ob, Mesh *mesh, int const draw_flag, + float *weights, int num, const int *indices) +{ + BMEditMesh *em = BKE_editmesh_from_object(ob); + unsigned char (*wtcol_v)[4]; + int numVerts = mesh->totvert; + int i; + + if (em) { + BKE_editmesh_color_ensure(em, BM_VERT); + wtcol_v = em->derivedVertColor; + } + else { + wtcol_v = MEM_malloc_arrayN(numVerts, sizeof(*wtcol_v), __func__); + } + + /* Weights are given by caller. */ + if (weights) { + float *w = weights; + /* If indices is not NULL, it means we do not have weights for all vertices, + * so we must create them (and set them to zero)... */ + if (indices) { + w = MEM_calloc_arrayN(numVerts, sizeof(float), "Temp weight array DM_update_weight_mcol"); + i = num; + while (i--) + w[indices[i]] = weights[i]; + } + + /* Convert float weights to colors. */ + calc_colors_from_weights_array(numVerts, w, wtcol_v); + + if (indices) + MEM_freeN(w); + } + else { + /* No weights given, take them from active vgroup(s). */ + calc_weightpaint_vert_array_mesh(ob, mesh, draw_flag, &G_dm_wcinfo, wtcol_v); + } + + if (em) { + /* editmesh draw function checks specifically for this */ + } + else { + const int totpoly = mesh->totpoly; + const int totloop = mesh->totloop; + unsigned char(*wtcol_l)[4] = CustomData_get_layer(&mesh->ldata, CD_PREVIEW_MLOOPCOL); + MLoop *mloop = mesh->mloop, *ml; + MPoly *mp = mesh->mpoly; + int l_index; + int j; + + /* now add to loops, so the data can be passed through the modifier stack + * If no CD_PREVIEW_MLOOPCOL existed yet, we have to add a new one! */ + if (!wtcol_l) { + wtcol_l = MEM_malloc_arrayN(totloop, sizeof(*wtcol_l), __func__); + CustomData_add_layer(&mesh->ldata, CD_PREVIEW_MLOOPCOL, CD_ASSIGN, wtcol_l, totloop); + } + + l_index = 0; + for (i = 0; i < totpoly; i++, mp++) { + ml = mloop + mp->loopstart; + + for (j = 0; j < mp->totloop; j++, ml++, l_index++) { + copy_v4_v4_uchar(&wtcol_l[l_index][0], + &wtcol_v[ml->v][0]); + } + } + MEM_freeN(wtcol_v); + + //dm->dirty |= DM_DIRTY_TESS_CDLAYERS; // XXX: Does Mesh need this? + } +} + static void DM_update_statvis_color(const Scene *scene, Object *ob, DerivedMesh *dm) { BMEditMesh *em = BKE_editmesh_from_object(ob); @@ -1742,6 +1976,32 @@ static void dm_ensure_display_normals(DerivedMesh *dm) } } +static void mesh_ensure_display_normals(Mesh *mesh) +{ + /* Note: mesh *may* have a poly CD_NORMAL layer (generated by a modifier needing poly normals e.g.). + * We do not use it here, though. And it should be tagged as temp! + */ + /* BLI_assert((CustomData_has_layer(&mesh->pdata, CD_NORMAL) == false)); */ + + if(mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL || !CustomData_has_layer(&mesh->pdata, CD_NORMAL)) { + float (*face_nors)[3] = NULL; + face_nors = MEM_malloc_arrayN(mesh->totpoly, sizeof(*face_nors), "face_nors"); + + /* if normals are dirty we want to calculate vertex normals too */ + bool only_face_normals = !(mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL); + + /* calculate face normals */ + BKE_mesh_calc_normals_poly( + mesh->mvert, NULL, mesh->totvert, mesh->mloop, mesh->mpoly, + mesh->totloop, mesh->totpoly, face_nors, + only_face_normals); + + CustomData_add_layer(&mesh->pdata, CD_NORMAL, CD_ASSIGN, face_nors, mesh->totpoly); + + mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL; + } +} + static void mesh_calc_modifiers( struct Depsgraph *depsgraph, Scene *scene, Object *ob, float (*inputVertexCos)[3], const bool useRenderParams, int useDeform, @@ -1749,7 +2009,7 @@ static void mesh_calc_modifiers( const int index, const bool useCache, const bool build_shapekey_layers, const bool allow_gpu, /* return args */ - DerivedMesh **r_deform, DerivedMesh **r_final) + Mesh **r_deform_mesh, Mesh **r_final_mesh) { Mesh *me = ob->data; /* Always get the vertex coordinates from the original mesh. Otherwise @@ -1760,7 +2020,6 @@ static void mesh_calc_modifiers( /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */ CustomDataMask mask, nextmask, previewmask = 0, append_mask = CD_MASK_ORIGINDEX; float (*deformedVerts)[3] = NULL; - DerivedMesh *dm = NULL, *orcodm, *clothorcodm, *finaldm; int numVerts = me->totvert; const int required_mode = useRenderParams ? eModifierMode_Render : eModifierMode_Realtime; bool isPrevDeform = false; @@ -1782,7 +2041,6 @@ static void mesh_calc_modifiers( const bool do_mod_wmcol = do_init_wmcol; const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH) != 0; - const float loop_normals_split_angle = me->smoothresh; VirtualModifierData virtualModifierData; @@ -1825,10 +2083,10 @@ static void mesh_calc_modifiers( datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, previewmask); curr = datamasks; - if (r_deform) { - *r_deform = NULL; + if (r_deform_mesh) { + *r_deform_mesh = NULL; } - *r_final = NULL; + *r_final_mesh = NULL; if (useDeform) { if (inputVertexCos) @@ -1852,7 +2110,7 @@ static void mesh_calc_modifiers( if (!deformedVerts) deformedVerts = BKE_mesh_vertexCos_get(mesh_orig_id, &numVerts); - modwrap_deformVerts(md, &mectx_deform, NULL, deformedVerts, numVerts); + modifier_deformVerts_ensure_normals(md, &mectx_deform, NULL, deformedVerts, numVerts); } else { break; @@ -1867,14 +2125,17 @@ static void mesh_calc_modifiers( * places that wish to use the original mesh but with deformed * coordinates (vpaint, etc.) */ - if (r_deform) { - *r_deform = CDDM_from_mesh(me); - - if (build_shapekey_layers) - add_shapekey_layers(dm, me, ob); + if (r_deform_mesh) { + BKE_id_copy_ex(NULL, &me->id, (ID**)r_deform_mesh, + LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_DEG_TAG, false); + + /* XXX: Is build_shapekey_layers ever even true? This should have crashed long ago... */ + BLI_assert(!build_shapekey_layers); + //if (build_shapekey_layers) + // add_shapekey_layers(*r_deform_mesh, me, ob); if (deformedVerts) { - CDDM_apply_vert_coords(*r_deform, deformedVerts); + BKE_mesh_apply_vert_coords(*r_deform_mesh, deformedVerts); } } } @@ -1890,9 +2151,9 @@ static void mesh_calc_modifiers( /* Now apply all remaining modifiers. If useDeform is off then skip * OnlyDeform ones. */ - dm = NULL; - orcodm = NULL; - clothorcodm = NULL; + Mesh *mesh = NULL; + Mesh *orco_mesh = NULL; + Mesh *cloth_orco_mesh = NULL; for (; md; md = md->next, curr = curr->next) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -1907,7 +2168,7 @@ static void mesh_calc_modifiers( continue; } - if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { + if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && mesh) { modifier_setError(md, "Modifier requires original data, bad stack position"); continue; } @@ -1958,26 +2219,24 @@ static void mesh_calc_modifiers( else mask = 0; - if (dm && (mask & CD_MASK_ORCO)) - add_orco_dm(ob, NULL, dm, orcodm, CD_ORCO); + if (mesh && (mask & CD_MASK_ORCO)) { + add_orco_mesh(ob, NULL, mesh, orco_mesh, CD_ORCO); + } /* How to apply modifier depends on (a) what we already have as - * a result of previous modifiers (could be a DerivedMesh or just + * a result of previous modifiers (could be a Mesh or just * deformed vertices) and (b) what type the modifier is. */ if (mti->type == eModifierTypeType_OnlyDeform) { /* No existing verts to deform, need to build them. */ if (!deformedVerts) { - if (dm) { - /* Deforming a derived mesh, read the vertex locations + if (mesh) { + /* Deforming a mesh, read the vertex locations * out of the mesh and deform them. Once done with this * run of deformers verts will be written back. */ - numVerts = dm->getNumVerts(dm); - deformedVerts = - MEM_malloc_arrayN(numVerts, sizeof(*deformedVerts), "dfmv"); - dm->getVertCos(dm, deformedVerts); + deformedVerts = BKE_mesh_vertexCos_get(mesh, &numVerts); } else { deformedVerts = BKE_mesh_vertexCos_get(mesh_orig_id, &numVerts); @@ -1988,45 +2247,41 @@ static void mesh_calc_modifiers( * to avoid giving bogus normals to the next modifier see: [#23673] */ if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { /* XXX, this covers bug #23673, but we may need normal calc for other types */ - if (dm && dm->type == DM_TYPE_CDDM) { - CDDM_apply_vert_coords(dm, deformedVerts); + if (mesh) { + BKE_mesh_apply_vert_coords(mesh, deformedVerts); } } - modwrap_deformVerts(md, &mectx_deform, dm, deformedVerts, numVerts); + modifier_deformVerts_ensure_normals(md, &mectx_deform, mesh, deformedVerts, numVerts); } else { - DerivedMesh *ndm; - /* determine which data layers are needed by following modifiers */ if (curr->next) nextmask = curr->next->mask; else nextmask = dataMask; - /* apply vertex coordinates or build a DerivedMesh as necessary */ - if (dm) { + /* apply vertex coordinates or build a Mesh as necessary */ + if (mesh) { if (deformedVerts) { - DerivedMesh *tdm = CDDM_copy(dm); - dm->release(dm); - dm = tdm; - - CDDM_apply_vert_coords(dm, deformedVerts); + BKE_mesh_apply_vert_coords(mesh, deformedVerts); } } else { - dm = CDDM_from_mesh(me); - ASSERT_IS_VALID_DM(dm); + BKE_id_copy_ex(NULL, &me->id, (ID**)&mesh, + LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_DEG_TAG, false); + ASSERT_IS_VALID_MESH(mesh); - if (build_shapekey_layers) - add_shapekey_layers(dm, me, ob); + // XXX: port to Mesh if build_shapekey_layers can ever be true + //if (build_shapekey_layers) + // add_shapekey_layers(mesh, me, ob); if (deformedVerts) { - CDDM_apply_vert_coords(dm, deformedVerts); + BKE_mesh_apply_vert_coords(mesh, deformedVerts); } if (do_init_wmcol) - DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); + mesh_update_weight_mcol(ob, mesh, draw_flag, NULL, 0, NULL); /* Constructive modifiers need to have an origindex * otherwise they wont have anywhere to copy the data from. @@ -2037,45 +2292,48 @@ static void mesh_calc_modifiers( */ if (need_mapping || (nextmask & CD_MASK_ORIGINDEX)) { /* calc */ - DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); - DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); - DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + CustomData_add_layer(&mesh->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert); + CustomData_add_layer(&mesh->edata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge); + CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totpoly); /* Not worth parallelizing this, gives less than 0.1% overall speedup in best of best cases... */ - range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); - range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); - range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0); + range_vn_i(CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX), mesh->totvert, 0); + range_vn_i(CustomData_get_layer(&mesh->edata, CD_ORIGINDEX), mesh->totedge, 0); + range_vn_i(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX), mesh->totpoly, 0); } } - /* set the DerivedMesh to only copy needed data */ + /* set the Mesh to only copy needed data */ mask = curr->mask; /* needMapping check here fixes bug [#28112], otherwise it's * possible that it won't be copied */ mask |= append_mask; - DM_set_only_copy(dm, mask | (need_mapping ? CD_MASK_ORIGINDEX : 0)); - + mesh_set_only_copy(mesh, mask | (need_mapping ? CD_MASK_ORIGINDEX : 0)); + /* add cloth rest shape key if needed */ if (mask & CD_MASK_CLOTH_ORCO) - add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO); + add_orco_mesh(ob, NULL, mesh, orco_mesh, CD_CLOTH_ORCO); /* add an origspace layer if needed */ if ((curr->mask) & CD_MASK_ORIGSPACE_MLOOP) { - if (!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) { - DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL); - DM_init_origspace(dm); + if (!CustomData_has_layer(&mesh->ldata, CD_ORIGSPACE_MLOOP)) { + CustomData_add_layer(&mesh->ldata, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL, mesh->totloop); + mesh_init_origspace(mesh); } } - ndm = modwrap_applyModifier(md, &mectx_apply, dm); - ASSERT_IS_VALID_DM(ndm); + Mesh *new_mesh = modifier_applyModifier_ensure_normals(md, &mectx_apply, mesh); + ASSERT_IS_VALID_MESH(new_mesh); - if (ndm) { - /* if the modifier returned a new dm, release the old one */ - if (dm && dm != ndm) dm->release(dm); + if (new_mesh) { + /* if the modifier returned a new mesh, release the old one */ + if (mesh && mesh != new_mesh) { + BLI_assert(mesh != me); + BKE_id_free(NULL, mesh); + } - dm = ndm; + mesh = new_mesh; if (deformedVerts) { if (deformedVerts != inputVertexCos) @@ -2085,43 +2343,51 @@ static void mesh_calc_modifiers( } } - /* create an orco derivedmesh in parallel */ + /* create an orco mesh in parallel */ if (nextmask & CD_MASK_ORCO) { - if (!orcodm) - orcodm = create_orco_dm(ob, me, NULL, CD_ORCO); + if (!orco_mesh) { + orco_mesh = create_orco_mesh(ob, me, NULL, CD_ORCO); + } nextmask &= ~CD_MASK_ORCO; - DM_set_only_copy(orcodm, nextmask | CD_MASK_ORIGINDEX | + mesh_set_only_copy(orco_mesh, nextmask | CD_MASK_ORIGINDEX | (mti->requiredDataMask ? mti->requiredDataMask(ob, md) : 0)); - ndm = modwrap_applyModifier(md, &mectx_orco, orcodm); - ASSERT_IS_VALID_DM(ndm); + new_mesh = modifier_applyModifier_ensure_normals(md, &mectx_orco, orco_mesh); + ASSERT_IS_VALID_MESH(new_mesh); - if (ndm) { - /* if the modifier returned a new dm, release the old one */ - if (orcodm && orcodm != ndm) orcodm->release(orcodm); - orcodm = ndm; + if (new_mesh) { + /* if the modifier returned a new mesh, release the old one */ + if (orco_mesh && orco_mesh != new_mesh) { + BLI_assert(orco_mesh != me); + BKE_id_free(NULL, orco_mesh); + } + + orco_mesh = new_mesh; } } - /* create cloth orco derivedmesh in parallel */ + /* create cloth orco mesh in parallel */ if (nextmask & CD_MASK_CLOTH_ORCO) { - if (!clothorcodm) - clothorcodm = create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO); + if (!cloth_orco_mesh) { + cloth_orco_mesh = create_orco_mesh(ob, me, NULL, CD_CLOTH_ORCO); + } nextmask &= ~CD_MASK_CLOTH_ORCO; - DM_set_only_copy(clothorcodm, nextmask | CD_MASK_ORIGINDEX); + mesh_set_only_copy(cloth_orco_mesh, nextmask | CD_MASK_ORIGINDEX); - ndm = modwrap_applyModifier(md, &mectx_orco, clothorcodm); - ASSERT_IS_VALID_DM(ndm); + new_mesh = modifier_applyModifier_ensure_normals(md, &mectx_orco, cloth_orco_mesh); + ASSERT_IS_VALID_DM(new_mesh); - if (ndm) { - /* if the modifier returned a new dm, release the old one */ - if (clothorcodm && clothorcodm != ndm) { - clothorcodm->release(clothorcodm); + if (new_mesh) { + /* if the modifier returned a new mesh, release the old one */ + if (cloth_orco_mesh && cloth_orco_mesh != new_mesh) { + BLI_assert(orco_mesh != me); + BKE_id_free(NULL, cloth_orco_mesh); } - clothorcodm = ndm; + + cloth_orco_mesh = new_mesh; } } @@ -2131,11 +2397,11 @@ static void mesh_calc_modifiers( append_mask |= CD_MASK_PREVIEW_MLOOPCOL; /* In case of active preview modifier, make sure preview mask remains for following modifiers. */ else if ((md == previewmd) && (do_mod_wmcol)) { - DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); + mesh_update_weight_mcol(ob, mesh, draw_flag, NULL, 0, NULL); append_mask |= CD_MASK_PREVIEW_MLOOPCOL; } - dm->deformedOnly = false; + mesh->runtime.deformed_only = false; } isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); @@ -2152,65 +2418,60 @@ static void mesh_calc_modifiers( for (md = firstmd; md; md = md->next) modifier_freeTemporaryData(md); - /* Yay, we are done. If we have a DerivedMesh and deformed vertices - * need to apply these back onto the DerivedMesh. If we have no - * DerivedMesh then we need to build one. + /* Yay, we are done. If we have a Mesh and deformed vertices + * need to apply these back onto the Mesh. If we have no + * Mesh then we need to build one. */ - if (dm && deformedVerts) { - finaldm = CDDM_copy(dm); - - dm->release(dm); + Mesh *final_mesh; - CDDM_apply_vert_coords(finaldm, deformedVerts); + if (mesh) { + final_mesh = mesh; -#if 0 /* For later nice mod preview! */ - /* In case we need modified weights in CD_PREVIEW_MCOL, we have to re-compute it. */ - if (do_final_wmcol) - DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); -#endif - } - else if (dm) { - finaldm = dm; + if (deformedVerts) { + BKE_mesh_apply_vert_coords(final_mesh, deformedVerts); + } #if 0 /* For later nice mod preview! */ /* In case we need modified weights in CD_PREVIEW_MCOL, we have to re-compute it. */ if (do_final_wmcol) - DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); + mesh_update_weight_mcol(ob, final_mesh, draw_flag, NULL, 0, NULL); #endif } else { - finaldm = CDDM_from_mesh(me); - - if (build_shapekey_layers) { - add_shapekey_layers(finaldm, me, ob); - } - + BKE_id_copy_ex(NULL, &me->id, (ID**)&final_mesh, + LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_DEG_TAG, false); + + //if (build_shapekey_layers) { + // add_shapekey_layers(final_mesh, me, ob); + //} + if (deformedVerts) { - CDDM_apply_vert_coords(finaldm, deformedVerts); + BKE_mesh_apply_vert_coords(final_mesh, deformedVerts); } /* In this case, we should never have weight-modifying modifiers in stack... */ if (do_init_wmcol) - DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); + mesh_update_weight_mcol(ob, final_mesh, draw_flag, NULL, 0, NULL); } /* add an orco layer if needed */ if (dataMask & CD_MASK_ORCO) { - add_orco_dm(ob, NULL, finaldm, orcodm, CD_ORCO); + add_orco_mesh(ob, NULL, final_mesh, orco_mesh, CD_ORCO); - if (r_deform && *r_deform) - add_orco_dm(ob, NULL, *r_deform, NULL, CD_ORCO); + if (r_deform_mesh && *r_deform_mesh) + add_orco_mesh(ob, NULL, *r_deform_mesh, NULL, CD_ORCO); } if (do_loop_normals) { /* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */ - DM_calc_loop_normals(finaldm, do_loop_normals, loop_normals_split_angle); + BKE_mesh_calc_normals_split(final_mesh); + // dm->dirty |= DM_DIRTY_TESS_CDLAYERS; XXX } if (sculpt_dyntopo == false) { /* watch this! after 2.75a we move to from tessface to looptri (by default) */ if (dataMask & CD_MASK_MFACE) { - DM_ensure_tessface(finaldm); + // DM_ensure_tessface(final_mesh); // XXX: port? } /* without this, drawing ngon tri's faces will show ugly tessellated face @@ -2223,22 +2484,24 @@ static void mesh_calc_modifiers( * If using loop normals, poly nors have already been computed. */ if (!do_loop_normals) { - dm_ensure_display_normals(finaldm); + mesh_ensure_display_normals(final_mesh); } } /* Some modifiers, like datatransfer, may generate those data as temp layer, we do not want to keep them, * as they are used by display code when available (i.e. even if autosmooth is disabled). */ - if (!do_loop_normals && CustomData_has_layer(&finaldm->loopData, CD_NORMAL)) { - CustomData_free_layers(&finaldm->loopData, CD_NORMAL, finaldm->numLoopData); + if (!do_loop_normals && CustomData_has_layer(&final_mesh->ldata, CD_NORMAL)) { + CustomData_free_layers(&final_mesh->ldata, CD_NORMAL, final_mesh->totloop); } - *r_final = finaldm; + *r_final_mesh = final_mesh; - if (orcodm) - orcodm->release(orcodm); - if (clothorcodm) - clothorcodm->release(clothorcodm); + if (orco_mesh) { + BKE_id_free(NULL, orco_mesh); + } + if (cloth_orco_mesh) { + BKE_id_free(NULL, cloth_orco_mesh); + } if (deformedVerts && deformedVerts != inputVertexCos) MEM_freeN(deformedVerts); @@ -2246,6 +2509,30 @@ static void mesh_calc_modifiers( BLI_linklist_free((LinkNode *)datamasks, NULL); } +static void mesh_calc_modifiers_dm( + struct Depsgraph *depsgraph, Scene *scene, Object *ob, float (*inputVertexCos)[3], + const bool useRenderParams, int useDeform, + const bool need_mapping, CustomDataMask dataMask, + const int index, const bool useCache, const bool build_shapekey_layers, + const bool allow_gpu, + /* return args */ + DerivedMesh **r_deformdm, DerivedMesh **r_finaldm) +{ + Mesh *deform_mesh = NULL, *final_mesh = NULL; + + mesh_calc_modifiers(depsgraph, scene, ob, inputVertexCos, useRenderParams, useDeform, + need_mapping, dataMask, index, useCache, build_shapekey_layers, allow_gpu, + (r_deformdm ? &deform_mesh : NULL), &final_mesh); + + if(deform_mesh) { + *r_deformdm = CDDM_from_mesh_ex(deform_mesh, CD_DUPLICATE); + BKE_id_free(NULL, deform_mesh); + } + + *r_finaldm = CDDM_from_mesh_ex(final_mesh, CD_DUPLICATE); + BKE_id_free(NULL, final_mesh); +} + float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *r_numVerts))[3] { BMIter iter; @@ -2643,7 +2930,7 @@ static void mesh_build_data( } #endif - mesh_calc_modifiers( + mesh_calc_modifiers_dm( depsgraph, scene, ob, NULL, false, 1, need_mapping, dataMask, -1, true, build_shapekey_layers, true, &ob->derivedDeform, &ob->derivedFinal); @@ -2792,7 +3079,7 @@ DerivedMesh *mesh_create_derived_render(struct Depsgraph *depsgraph, Scene *scen { DerivedMesh *final; - mesh_calc_modifiers( + mesh_calc_modifiers_dm( depsgraph, scene, ob, NULL, true, 1, false, dataMask, -1, false, false, false, NULL, &final); @@ -2803,7 +3090,7 @@ DerivedMesh *mesh_create_derived_index_render(struct Depsgraph *depsgraph, Scene { DerivedMesh *final; - mesh_calc_modifiers( + mesh_calc_modifiers_dm( depsgraph, scene, ob, NULL, true, 1, false, dataMask, index, false, false, false, NULL, &final); @@ -2822,7 +3109,7 @@ DerivedMesh *mesh_create_derived_view( */ ob->transflag |= OB_NO_PSYS_UPDATE; - mesh_calc_modifiers( + mesh_calc_modifiers_dm( depsgraph, scene, ob, NULL, false, 1, false, dataMask, -1, false, false, false, NULL, &final); @@ -2837,7 +3124,7 @@ DerivedMesh *mesh_create_derived_no_deform( { DerivedMesh *final; - mesh_calc_modifiers( + mesh_calc_modifiers_dm( depsgraph, scene, ob, vertCos, false, 0, false, dataMask, -1, false, false, false, NULL, &final); @@ -2851,7 +3138,7 @@ DerivedMesh *mesh_create_derived_no_deform_render( { DerivedMesh *final; - mesh_calc_modifiers( + mesh_calc_modifiers_dm( depsgraph, scene, ob, vertCos, true, 0, false, dataMask, -1, false, false, false, NULL, &final); @@ -3149,6 +3436,76 @@ void DM_init_origspace(DerivedMesh *dm) BLI_array_free(vcos_2d); } +static void mesh_init_origspace(Mesh *mesh) +{ + const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; + + OrigSpaceLoop *lof_array = CustomData_get_layer(&mesh->ldata, CD_ORIGSPACE_MLOOP); + const int numpoly = mesh->totpoly; + // const int numloop = mesh->totloop; + MVert *mv = mesh->mvert; + MLoop *ml = mesh->mloop; + MPoly *mp = mesh->mpoly; + int i, j, k; + + float (*vcos_2d)[2] = NULL; + BLI_array_staticdeclare(vcos_2d, 64); + + for (i = 0; i < numpoly; i++, mp++) { + OrigSpaceLoop *lof = lof_array + mp->loopstart; + + if (mp->totloop == 3 || mp->totloop == 4) { + for (j = 0; j < mp->totloop; j++, lof++) { + copy_v2_v2(lof->uv, default_osf[j]); + } + } + else { + MLoop *l = &ml[mp->loopstart]; + float p_nor[3], co[3]; + float mat[3][3]; + + float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX}; + float translate[2], scale[2]; + + BKE_mesh_calc_poly_normal(mp, l, mv, p_nor); + axis_dominant_v3_to_m3(mat, p_nor); + + BLI_array_clear(vcos_2d); + BLI_array_reserve(vcos_2d, mp->totloop); + for (j = 0; j < mp->totloop; j++, l++) { + mul_v3_m3v3(co, mat, mv[l->v].co); + copy_v2_v2(vcos_2d[j], co); + + for (k = 0; k < 2; k++) { + if (co[k] > max[k]) + max[k] = co[k]; + else if (co[k] < min[k]) + min[k] = co[k]; + } + } + + /* Brings min to (0, 0). */ + negate_v2_v2(translate, min); + + /* Scale will bring max to (1, 1). */ + sub_v2_v2v2(scale, max, min); + if (scale[0] == 0.0f) + scale[0] = 1e-9f; + if (scale[1] == 0.0f) + scale[1] = 1e-9f; + invert_v2(scale); + + /* Finally, transform all vcos_2d into ((0, 0), (1, 1)) square and assing them as origspace. */ + for (j = 0; j < mp->totloop; j++, lof++) { + add_v2_v2v2(lof->uv, vcos_2d[j], translate); + mul_v2_v2(lof->uv, scale); + } + } + } + + //mesh->dirty |= DM_DIRTY_TESS_CDLAYERS; // XXX: Needed for Mesh? + BLI_array_free(vcos_2d); +} /* derivedmesh info printing function, diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 63846b31c33..f80096b39eb 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1991,7 +1991,10 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm) /* printf("rebuild pose %s, %d bones\n", ob->id.name, counter); */ /* synchronize protected layers with proxy */ - if (ob->proxy) { + /* HACK! To preserve 2.7x behavior that you always can pose even locked bones, + * do not do any restauration if this is a COW temp copy! */ + /* Switched back to just NO_MAIN tag, for some reasons (c) using COW tag was working this morning, but not anymore... */ + if (ob->proxy != NULL && (ob->id.tag & LIB_TAG_NO_MAIN) == 0) { BKE_object_copy_proxy_drivers(ob, ob->proxy); pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected); } diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 236b965ec34..3f78b096115 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -104,8 +104,6 @@ void BKE_blender_free(void) BKE_sequencer_cache_destruct(); IMB_moviecache_destruct(); - BKE_layer_exit(); - free_nodesystem(); } diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index c8d044bcd00..b3ea3de6ea9 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -1258,54 +1258,42 @@ BVHTree *BKE_bvhtree_from_mesh_get( struct BVHTreeFromMesh *data, struct Mesh *mesh, const int type, const int tree_type) { - BVHTree *tree = NULL; - - BVHTree_NearestPointCallback nearest_callback = NULL; - BVHTree_RayCastCallback raycast_callback = NULL; - - MVert *mvert = NULL; - MEdge *medge = NULL; - MFace *mface = NULL; - MLoop *mloop = NULL; - const MLoopTri *looptri = NULL; - bool vert_allocated = false; - bool edge_allocated = false; - bool face_allocated = false; - bool loop_allocated = false; - bool looptri_allocated = false; + struct BVHTreeFromMesh data_cp = {0}; BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ); - bool in_cache = bvhcache_find(mesh->runtime.bvh_cache, type, &tree); + data_cp.cached = bvhcache_find(mesh->runtime.bvh_cache, type, &data_cp.tree); BLI_rw_mutex_unlock(&cache_rwlock); - if (in_cache && tree == NULL) { + if (data_cp.cached && data_cp.tree == NULL) { memset(data, 0, sizeof(*data)); - return tree; + return data_cp.tree; } switch (type) { case BVHTREE_FROM_VERTS: case BVHTREE_FROM_LOOSEVERTS: - raycast_callback = mesh_verts_spherecast; + data_cp.raycast_callback = mesh_verts_spherecast; - mvert = mesh->mvert; + data_cp.vert = mesh->mvert; - if (in_cache == false) { + if (data_cp.cached == false) { BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); - in_cache = bvhcache_find(mesh->runtime.bvh_cache, type, &tree); - if (in_cache == false) { + data_cp.cached = bvhcache_find( + mesh->runtime.bvh_cache, type, &data_cp.tree); + + if (data_cp.cached == false) { BLI_bitmap *loose_verts_mask = NULL; int loose_vert_len = -1; int verts_len = mesh->totvert; if (type == BVHTREE_FROM_LOOSEVERTS) { loose_verts_mask = loose_verts_map_get( - mesh->medge, mesh->totedge, mvert, + mesh->medge, mesh->totedge, data_cp.vert, verts_len, &loose_vert_len); } - tree = bvhtree_from_mesh_verts_create_tree( - 0.0, tree_type, 6, mvert, verts_len, + data_cp.tree = bvhtree_from_mesh_verts_create_tree( + 0.0, tree_type, 6, data_cp.vert, verts_len, loose_verts_mask, loose_vert_len); if (loose_verts_mask != NULL) { @@ -1314,7 +1302,7 @@ BVHTree *BKE_bvhtree_from_mesh_get( /* Save on cache for later use */ /* printf("BVHTree built and saved on cache\n"); */ - bvhcache_insert(&mesh->runtime.bvh_cache, tree, type); + bvhcache_insert(&mesh->runtime.bvh_cache, data_cp.tree, type); } BLI_rw_mutex_unlock(&cache_rwlock); } @@ -1322,27 +1310,27 @@ BVHTree *BKE_bvhtree_from_mesh_get( case BVHTREE_FROM_EDGES: case BVHTREE_FROM_LOOSEEDGES: - nearest_callback = mesh_edges_nearest_point; - raycast_callback = mesh_edges_spherecast; + data_cp.nearest_callback = mesh_edges_nearest_point; + data_cp.raycast_callback = mesh_edges_spherecast; - mvert = mesh->mvert; - medge = mesh->medge; + data_cp.vert = mesh->mvert; + data_cp.edge = mesh->medge; - if (in_cache == false) { + if (data_cp.cached == false) { BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); - in_cache = bvhcache_find(mesh->runtime.bvh_cache, type, &tree); - if (in_cache == false) { + data_cp.cached = bvhcache_find(mesh->runtime.bvh_cache, type, &data_cp.tree); + if (data_cp.cached == false) { BLI_bitmap *loose_edges_mask = NULL; int loose_edges_len = -1; int edges_len = mesh->totedge; if (type == BVHTREE_FROM_LOOSEEDGES) { loose_edges_mask = loose_edges_map_get( - medge, edges_len, &loose_edges_len); + data_cp.edge, edges_len, &loose_edges_len); } - tree = bvhtree_from_mesh_edges_create_tree( - mvert, medge, edges_len, + data_cp.tree = bvhtree_from_mesh_edges_create_tree( + data_cp.vert, data_cp.edge, edges_len, loose_edges_mask, loose_edges_len, 0.0, tree_type, 6); if (loose_edges_mask != NULL) { @@ -1351,114 +1339,91 @@ BVHTree *BKE_bvhtree_from_mesh_get( /* Save on cache for later use */ /* printf("BVHTree built and saved on cache\n"); */ - bvhcache_insert(&mesh->runtime.bvh_cache, tree, type); + bvhcache_insert(&mesh->runtime.bvh_cache, data_cp.tree, type); } BLI_rw_mutex_unlock(&cache_rwlock); } break; case BVHTREE_FROM_FACES: - nearest_callback = mesh_faces_nearest_point; - raycast_callback = mesh_faces_spherecast; + data_cp.nearest_callback = mesh_faces_nearest_point; + data_cp.raycast_callback = mesh_faces_spherecast; - mvert = mesh->mvert; - mface = mesh->mface; + data_cp.vert = mesh->mvert; + data_cp.face = mesh->mface; - if (in_cache == false) { + if (data_cp.cached == false) { BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); - in_cache = bvhcache_find(mesh->runtime.bvh_cache, BVHTREE_FROM_FACES, &tree); - if (in_cache == false) { + data_cp.cached = bvhcache_find( + mesh->runtime.bvh_cache, BVHTREE_FROM_FACES, &data_cp.tree); + if (data_cp.cached == false) { int num_faces = mesh->totface; BLI_assert(!(num_faces == 0 && mesh->totpoly != 0)); - tree = bvhtree_from_mesh_faces_create_tree( - 0.0, tree_type, 6, mvert, mface, num_faces, NULL, -1); + data_cp.tree = bvhtree_from_mesh_faces_create_tree( + 0.0, tree_type, 6, data_cp.vert, + data_cp.face, num_faces, NULL, -1); /* Save on cache for later use */ /* printf("BVHTree built and saved on cache\n"); */ - bvhcache_insert(&mesh->runtime.bvh_cache, tree, BVHTREE_FROM_FACES); + bvhcache_insert( + &mesh->runtime.bvh_cache, data_cp.tree, BVHTREE_FROM_FACES); } BLI_rw_mutex_unlock(&cache_rwlock); } break; case BVHTREE_FROM_LOOPTRI: - nearest_callback = mesh_looptri_nearest_point; - raycast_callback = mesh_looptri_spherecast; + data_cp.nearest_callback = mesh_looptri_nearest_point; + data_cp.raycast_callback = mesh_looptri_spherecast; - mvert = mesh->mvert; - mloop = mesh->mloop; + data_cp.vert = mesh->mvert; + data_cp.loop = mesh->mloop; /* TODO: store looptris somewhere? */ - looptri = BKE_mesh_runtime_looptri_ensure(mesh); + data_cp.looptri = BKE_mesh_runtime_looptri_ensure(mesh); - if (in_cache == false) { + if (data_cp.cached == false) { BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); - in_cache = bvhcache_find(mesh->runtime.bvh_cache, BVHTREE_FROM_LOOPTRI, &tree); - if (in_cache == false) { + data_cp.cached = bvhcache_find( + mesh->runtime.bvh_cache, BVHTREE_FROM_LOOPTRI, &data_cp.tree); + if (data_cp.cached == false) { int looptri_num = BKE_mesh_runtime_looptri_len(mesh); /* this assert checks we have looptris, * if not caller should use DM_ensure_looptri() */ BLI_assert(!(looptri_num == 0 && mesh->totpoly != 0)); - tree = bvhtree_from_mesh_looptri_create_tree( + data_cp.tree = bvhtree_from_mesh_looptri_create_tree( 0.0, tree_type, 6, - mvert, mloop, looptri, looptri_num, NULL, -1); + data_cp.vert, data_cp.loop, + data_cp.looptri, looptri_num, NULL, -1); /* Save on cache for later use */ /* printf("BVHTree built and saved on cache\n"); */ - bvhcache_insert(&mesh->runtime.bvh_cache, tree, BVHTREE_FROM_LOOPTRI); + bvhcache_insert( + &mesh->runtime.bvh_cache, data_cp.tree, BVHTREE_FROM_LOOPTRI); } BLI_rw_mutex_unlock(&cache_rwlock); } break; } - if (tree != NULL) { + if (data_cp.tree != NULL) { #ifdef DEBUG - if (BLI_bvhtree_get_tree_type(tree) != tree_type) { - printf("tree_type %d obtained instead of %d\n", BLI_bvhtree_get_tree_type(tree), tree_type); + if (BLI_bvhtree_get_tree_type(data_cp.tree) != tree_type) { + printf("tree_type %d obtained instead of %d\n", + BLI_bvhtree_get_tree_type(data_cp.tree), tree_type); } #endif - data->tree = tree; - - data->nearest_callback = nearest_callback; - data->raycast_callback = raycast_callback; - - data->vert = mvert; - data->edge = medge; - data->face = mface; - data->loop = mloop; - data->looptri = looptri; - data->vert_allocated = vert_allocated; - data->edge_allocated = edge_allocated; - data->face_allocated = face_allocated; - data->loop_allocated = loop_allocated; - data->looptri_allocated = looptri_allocated; - - data->cached = true; + data_cp.cached = true; + memcpy(data, &data_cp, sizeof(*data)); } else { - if (vert_allocated) { - MEM_freeN(mvert); - } - if (edge_allocated) { - MEM_freeN(medge); - } - if (face_allocated) { - MEM_freeN(mface); - } - if (loop_allocated) { - MEM_freeN(mloop); - } - if (looptri_allocated) { - MEM_freeN((void *)looptri); - } - + free_bvhtree_from_mesh(&data_cp); memset(data, 0, sizeof(*data)); } - return tree; + return data_cp.tree; } /** \} */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 46dd376e065..b77582b7ec3 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -608,6 +608,9 @@ DerivedMesh *CDDM_from_mesh_ex(Mesh *mesh, int alloctype) DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, 0 /* mesh->totface */, mesh->totloop, mesh->totpoly); + /* This should actually be dm->deformedOnly = mesh->runtime.deformed_only, + * but only if the original mesh had its deformed_only flag correctly set + * (which isn't generally the case). */ dm->deformedOnly = 1; dm->cd_flag = mesh->cd_flag; diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 45877558ad3..685c007da6b 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -63,11 +63,6 @@ /* prototype */ -struct EngineSettingsCB_Type; -static IDProperty *collection_engine_settings_create(struct EngineSettingsCB_Type *ces_type, const bool populate); -static IDProperty *collection_engine_get(IDProperty *root, const char *engine_name); -static void collection_engine_settings_init(IDProperty *root, const bool populate); -static void layer_engine_settings_init(IDProperty *root, const bool populate); static void object_bases_iterator_next(BLI_Iterator *iter, const int flag); @@ -85,7 +80,7 @@ static LayerCollection *layer_collection_add(ListBase *lb_parent, Collection *co static void layer_collection_free(ViewLayer *view_layer, LayerCollection *lc) { if (lc == view_layer->active_collection) { - view_layer->active_collection = NULL; + view_layer->active_collection = view_layer->layer_collections.first; } for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { @@ -215,11 +210,6 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user) } BLI_freelistN(&view_layer->layer_collections); - if (view_layer->properties_evaluated) { - IDP_FreeProperty(view_layer->properties_evaluated); - MEM_freeN(view_layer->properties_evaluated); - } - for (ViewLayerEngineData *sled = view_layer->drawdata.first; sled; sled = sled->next) { if (sled->storage) { if (sled->free) { @@ -383,7 +373,6 @@ void BKE_view_layer_copy_data( BKE_freestyle_config_copy(&view_layer_dst->freestyle_config, &view_layer_src->freestyle_config, flag); view_layer_dst->stats = NULL; - view_layer_dst->properties_evaluated = NULL; /* Clear temporary data. */ BLI_listbase_clear(&view_layer_dst->drawdata); @@ -436,8 +425,21 @@ LayerCollection *BKE_layer_collection_get_active(ViewLayer *view_layer) return view_layer->active_collection; } +/* + * Activate collection + */ +bool BKE_layer_collection_activate(ViewLayer *view_layer, LayerCollection *lc) +{ + if (lc->flag & LAYER_COLLECTION_EXCLUDE) { + return false; + } + + view_layer->active_collection = lc; + return true; +} + /** - * Active parent collection + * Activate first parent collection */ LayerCollection *BKE_layer_collection_activate_parent(ViewLayer *view_layer, LayerCollection *lc) { @@ -450,6 +452,11 @@ LayerCollection *BKE_layer_collection_activate_parent(ViewLayer *view_layer, Lay lc = NULL; } + if (lc && (lc->flag & LAYER_COLLECTION_EXCLUDE)) { + /* Don't activate excluded collections. */ + return BKE_layer_collection_activate_parent(view_layer, lc); + } + if (!lc) { lc = view_layer->layer_collections.first; } @@ -660,7 +667,12 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer) view_layer->object_bases = new_object_bases; /* Always set a valid active collection. */ - if (view_layer->active_collection == NULL) { + LayerCollection *active = view_layer->active_collection; + + if (active && (active->flag & LAYER_COLLECTION_EXCLUDE)) { + BKE_layer_collection_activate_parent(view_layer, active); + } + else if (active == NULL) { view_layer->active_collection = view_layer->layer_collections.first; } } @@ -838,409 +850,6 @@ void BKE_override_layer_collection_boolean_add(struct LayerCollection *layer_col TODO_LAYER_OVERRIDE; } -/* ---------------------------------------------------------------------- */ -/* Engine Settings */ - -ListBase R_layer_collection_engines_settings_callbacks = {NULL, NULL}; -ListBase R_view_layer_engines_settings_callbacks = {NULL, NULL}; - -typedef struct EngineSettingsCB_Type { - struct EngineSettingsCB_Type *next, *prev; - - char name[MAX_NAME]; /* engine name */ - - EngineSettingsCB callback; - -} EngineSettingsCB_Type; - -static void create_engine_settings_scene(IDProperty *root, EngineSettingsCB_Type *es_type) -{ - if (collection_engine_get(root, es_type->name)) { - return; - } - - IDProperty *props = collection_engine_settings_create(es_type, true); - IDP_AddToGroup(root, props); -} - -static void create_layer_collection_engine_settings_scene(Scene *scene, EngineSettingsCB_Type *es_type) -{ - create_engine_settings_scene(scene->collection_properties, es_type); -} - -static void create_view_layer_engine_settings_scene(Scene *scene, EngineSettingsCB_Type *es_type) -{ - create_engine_settings_scene(scene->layer_properties, es_type); -} - -static void create_layer_collection_engines_settings_scene(Scene *scene, EngineSettingsCB_Type *es_type) -{ - /* Populate the scene with the new settings. */ - create_layer_collection_engine_settings_scene(scene, es_type); -} - -static void create_view_layer_engines_settings_scene(Scene *scene, EngineSettingsCB_Type *es_type) -{ - /* Populate the scene with the new settings. */ - create_view_layer_engine_settings_scene(scene, es_type); -} - -static EngineSettingsCB_Type *engine_settings_callback_register(const char *engine_name, EngineSettingsCB func, ListBase *lb) -{ - EngineSettingsCB_Type *es_type; - - /* Cleanup in case it existed. */ - es_type = BLI_findstring(lb, engine_name, offsetof(EngineSettingsCB_Type, name)); - - if (es_type) { - BLI_remlink(lb, es_type); - MEM_freeN(es_type); - } - - es_type = MEM_callocN(sizeof(EngineSettingsCB_Type), __func__); - BLI_strncpy_utf8(es_type->name, engine_name, sizeof(es_type->name)); - es_type->callback = func; - BLI_addtail(lb, es_type); - - return es_type; -} - -void BKE_layer_collection_engine_settings_callback_register( - Main *bmain, const char *engine_name, EngineSettingsCB func) -{ - EngineSettingsCB_Type *es_type = - engine_settings_callback_register(engine_name, func, &R_layer_collection_engines_settings_callbacks); - - if (bmain) { - /* Populate all of the collections of the scene with those settings. */ - for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { - create_layer_collection_engines_settings_scene(scene, es_type); - } - } -} - -void BKE_view_layer_engine_settings_callback_register( - Main *bmain, const char *engine_name, EngineSettingsCB func) -{ - EngineSettingsCB_Type *es_type = - engine_settings_callback_register(engine_name, func, &R_view_layer_engines_settings_callbacks); - - if (bmain) { - /* Populate all of the collections of the scene with those settings. */ - for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { - create_view_layer_engines_settings_scene(scene, es_type); - } - } -} - -void BKE_layer_collection_engine_settings_callback_free(void) -{ - BLI_freelistN(&R_layer_collection_engines_settings_callbacks); -} - -void BKE_view_layer_engine_settings_callback_free(void) -{ - BLI_freelistN(&R_view_layer_engines_settings_callbacks); -} - -/** - * Create a root IDProperty for this engine - * - * \param populate whether we want to pre-fill the collection with the default properties - */ -static IDProperty *collection_engine_settings_create(EngineSettingsCB_Type *es_type, const bool populate) -{ - IDProperty *props; - IDPropertyTemplate val = {0}; - - props = IDP_New(IDP_GROUP, &val, es_type->name); - props->subtype = IDP_GROUP_SUB_ENGINE_RENDER; - - /* properties */ - if (populate) { - es_type->callback(NULL, props); - } - - return props; -} - -static void layer_collection_create_render_settings(IDProperty *root, const bool populate) -{ - EngineSettingsCB_Type *es_type; - for (es_type = R_layer_collection_engines_settings_callbacks.first; es_type; es_type = es_type->next) { - IDProperty *props = collection_engine_settings_create(es_type, populate); - IDP_AddToGroup(root, props); - } -} - -static void view_layer_create_render_settings(IDProperty *root, const bool populate) -{ - EngineSettingsCB_Type *es_type; - for (es_type = R_view_layer_engines_settings_callbacks.first; es_type; es_type = es_type->next) { - IDProperty *props = collection_engine_settings_create(es_type, populate); - IDP_AddToGroup(root, props); - } -} - -/** - * Return collection enginne settings for either Object s of LayerCollection s - */ -static IDProperty *collection_engine_get(IDProperty *root, const char *engine_name) -{ - return IDP_GetPropertyFromGroup(root, engine_name); -} - -/** - * Return layer collection engine settings for specified engine in the scene - */ -IDProperty *BKE_layer_collection_engine_scene_get(Scene *scene, const char *engine_name) -{ - return collection_engine_get(scene->collection_properties, engine_name); -} - -/** - * Return scene layer engine settings for specified engine in the scene - */ -IDProperty *BKE_view_layer_engine_scene_get(Scene *scene, const char *engine_name) -{ - return collection_engine_get(scene->layer_properties, engine_name); -} - -/** - * Return scene layer evaluated engine settings for specified engine - */ -IDProperty *BKE_view_layer_engine_evaluated_get(ViewLayer *view_layer, const char *engine_name) -{ - return collection_engine_get(view_layer->properties_evaluated, engine_name); -} - -/* ---------------------------------------------------------------------- */ -/* Engine Settings Properties */ - -void BKE_collection_engine_property_add_float(IDProperty *props, const char *name, float value) -{ - IDPropertyTemplate val = {0}; - val.f = value; - IDP_AddToGroup(props, IDP_New(IDP_FLOAT, &val, name)); -} - -void BKE_collection_engine_property_add_float_array( - IDProperty *props, const char *name, const float *values, const int array_length) -{ - IDPropertyTemplate val = {0}; - val.array.len = array_length; - val.array.type = IDP_FLOAT; - - IDProperty *idprop = IDP_New(IDP_ARRAY, &val, name); - memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len); - IDP_AddToGroup(props, idprop); -} - -void BKE_collection_engine_property_add_int(IDProperty *props, const char *name, int value) -{ - IDPropertyTemplate val = {0}; - val.i = value; - IDP_AddToGroup(props, IDP_New(IDP_INT, &val, name)); -} - -void BKE_collection_engine_property_add_bool(IDProperty *props, const char *name, bool value) -{ - IDPropertyTemplate val = {0}; - val.i = value; - IDP_AddToGroup(props, IDP_New(IDP_INT, &val, name)); -} - -int BKE_collection_engine_property_value_get_int(IDProperty *props, const char *name) -{ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, name); - return idprop ? IDP_Int(idprop) : 0; -} - -float BKE_collection_engine_property_value_get_float(IDProperty *props, const char *name) -{ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, name); - return idprop ? IDP_Float(idprop) : 0.0f; -} - -const float *BKE_collection_engine_property_value_get_float_array(IDProperty *props, const char *name) -{ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, name); - return idprop ? IDP_Array(idprop) : NULL; -} - -bool BKE_collection_engine_property_value_get_bool(IDProperty *props, const char *name) -{ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, name); - return idprop ? IDP_Int(idprop) : 0; -} - -void BKE_collection_engine_property_value_set_int(IDProperty *props, const char *name, int value) -{ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, name); - IDP_Int(idprop) = value; -} - -void BKE_collection_engine_property_value_set_float(IDProperty *props, const char *name, float value) -{ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, name); - IDP_Float(idprop) = value; -} - -void BKE_collection_engine_property_value_set_float_array(IDProperty *props, const char *name, const float *values) -{ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, name); - memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len); -} - -void BKE_collection_engine_property_value_set_bool(IDProperty *props, const char *name, bool value) -{ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, name); - IDP_Int(idprop) = value; -} - -/* Engine Settings recalculate */ - -/* get all the default settings defined in scene and merge them here */ -static void collection_engine_settings_init(IDProperty *root, const bool populate) -{ - /* render engines */ - layer_collection_create_render_settings(root, populate); -} - -/* get all the default settings defined in scene and merge them here */ -static void layer_engine_settings_init(IDProperty *root, const bool populate) -{ - /* render engines */ - view_layer_create_render_settings(root, populate); -} - -/** - * Initialize the layer collection render setings - * It's used mainly for scenes - */ -void BKE_layer_collection_engine_settings_create(IDProperty *root) -{ - collection_engine_settings_init(root, true); -} - -/** - * Initialize the render setings - * It's used mainly for scenes - */ -void BKE_view_layer_engine_settings_create(IDProperty *root) -{ - layer_engine_settings_init(root, true); -} - -/** - * Reference of IDProperty group scene collection settings - * Used when reading blendfiles, to see if there is any missing settings. - */ -static struct { - struct { - IDProperty *collection_properties; - IDProperty *render_settings; - } scene; - IDProperty *view_layer; - IDProperty *layer_collection; -} root_reference = { - .scene = {NULL, NULL}, - .view_layer = NULL, - .layer_collection = NULL, -}; - -/** - * Free the reference scene collection settings IDProperty group. - */ -static void engine_settings_validate_init(void) -{ - IDPropertyTemplate val = {0}; - - /* LayerCollection engine settings. */ - if (root_reference.scene.collection_properties == NULL) { - root_reference.scene.collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - collection_engine_settings_init(root_reference.scene.collection_properties, true); - } - - if (root_reference.layer_collection == NULL) { - root_reference.layer_collection = IDP_New(IDP_GROUP, &val, ROOT_PROP); - collection_engine_settings_init(root_reference.layer_collection, false); - } - - /* Render engine setting. */ - if (root_reference.scene.render_settings == NULL) { - root_reference.scene.render_settings = IDP_New(IDP_GROUP, &val, ROOT_PROP); - layer_engine_settings_init(root_reference.scene.render_settings, true); - } - - if (root_reference.view_layer == NULL) { - root_reference.view_layer = IDP_New(IDP_GROUP, &val, ROOT_PROP); - layer_engine_settings_init(root_reference.view_layer, false); - } -} - -/** - * Free the reference scene collection settings IDProperty group. - */ -static void layer_collection_engine_settings_validate_free(void) -{ - IDProperty *idprops[] = { - root_reference.scene.render_settings, - root_reference.scene.collection_properties, - root_reference.view_layer, - root_reference.layer_collection, - NULL, - }; - - IDProperty **idprop = &idprops[0]; - while (*idprop) { - if (*idprop) { - IDP_FreeProperty(*idprop); - MEM_freeN(*idprop); - *idprop = NULL; - idprop++; - } - } -} - -/** - * Make sure Scene has all required collection settings. - */ -void BKE_layer_collection_engine_settings_validate_scene(Scene *scene) -{ - if (root_reference.scene.collection_properties == NULL) { - engine_settings_validate_init(); - } - - if (scene->collection_properties == NULL) { - IDPropertyTemplate val = {0}; - scene->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - BKE_layer_collection_engine_settings_create(scene->collection_properties); - } - else { - IDP_MergeGroup(scene->collection_properties, root_reference.scene.collection_properties, false); - } -} - -/** - * Make sure Scene has all required collection settings. - */ -void BKE_view_layer_engine_settings_validate_scene(Scene *scene) -{ - if (root_reference.scene.render_settings == NULL) { - engine_settings_validate_init(); - } - - if (scene->layer_properties == NULL) { - IDPropertyTemplate val = {0}; - scene->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - BKE_view_layer_engine_settings_create(scene->layer_properties); - } - else { - IDP_MergeGroup(scene->layer_properties, root_reference.scene.render_settings, false); - } -} - /** \} */ /* Iterators */ @@ -1537,28 +1146,8 @@ void BKE_view_layer_bases_in_mode_iterator_end(BLI_Iterator *UNUSED(iter)) /* Evaluation */ -/** - * Reset props - * - * If props_ref is pasted, copy props from it - */ -static void idproperty_reset(IDProperty **props, IDProperty *props_ref) -{ - IDPropertyTemplate val = {0}; - - if (*props) { - IDP_FreeProperty(*props); - MEM_freeN(*props); - } - *props = IDP_New(IDP_GROUP, &val, ROOT_PROP); - - if (props_ref) { - IDP_MergeGroup(*props, props_ref, true); - } -} - void BKE_layer_eval_view_layer(struct Depsgraph *depsgraph, - struct Scene *scene, + struct Scene *UNUSED(scene), ViewLayer *view_layer) { DEG_debug_print_eval(depsgraph, __func__, view_layer->name, view_layer); @@ -1576,15 +1165,6 @@ void BKE_layer_eval_view_layer(struct Depsgraph *depsgraph, } } - /* Sync properties from scene to scene layer. */ - if (scene) { - idproperty_reset(&view_layer->properties_evaluated, scene->layer_properties); - IDP_MergeGroup(view_layer->properties_evaluated, scene->collection_properties, true); - } - else { - idproperty_reset(&view_layer->properties_evaluated, NULL); - } - /* TODO(sergey): Is it always required? */ view_layer->flag |= VIEW_LAYER_ENGINE_DIRTY; @@ -1613,11 +1193,3 @@ void BKE_layer_eval_view_layer_indexed(struct Depsgraph *depsgraph, BLI_assert(view_layer != NULL); BKE_layer_eval_view_layer(depsgraph, scene, view_layer); } - -/** - * Free any static allocated memory. - */ -void BKE_layer_exit(void) -{ - layer_collection_engine_settings_validate_free(); -} diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index a64eb5aa071..aea3e5f4281 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -551,9 +551,20 @@ void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int BKE_mesh_update_customdata_pointers(me_dst, do_tessface); me_dst->edit_btmesh = NULL; + + /* Call BKE_mesh_runtime_reset? */ me_dst->runtime.batch_cache = NULL; + me_dst->runtime.looptris.array = NULL; me_dst->runtime.bvh_cache = NULL; + if (me_src->id.tag & LIB_TAG_NO_MAIN) { + me_dst->runtime.deformed_only = me_src->runtime.deformed_only; + } + else { + /* This is a direct copy of a main mesh, so for now it has the same topology. */ + me_dst->runtime.deformed_only = 1; + } + me_dst->mselect = MEM_dupallocN(me_dst->mselect); me_dst->bb = MEM_dupallocN(me_dst->bb); diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 8301b6a42b1..2b43d49a10f 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -972,7 +972,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata, } /** - * \see #DM_is_valid to call on derived meshes + * Validates and corrects a Mesh. * * \returns true if a change is made. */ @@ -1012,6 +1012,42 @@ int BKE_mesh_validate(Mesh *me, const int do_verbose, const int cddata_check_mas } /** + * Checks if a Mesh is valid without any modification. This is always verbose. + * + * \see #DM_is_valid to call on derived meshes + * + * \returns is_valid. + */ +bool BKE_mesh_is_valid(Mesh *me) +{ + const bool do_verbose = true; + const bool do_fixes = false; + + bool is_valid = true; + bool changed = true; + + is_valid &= BKE_mesh_validate_all_customdata( + &me->vdata, &me->edata, &me->ldata, &me->pdata, + false, /* setting mask here isn't useful, gives false positives */ + do_verbose, do_fixes, &changed); + + is_valid &= BKE_mesh_validate_arrays( + me, + me->mvert, me->totvert, + me->medge, me->totedge, + me->mface, me->totface, + me->mloop, me->totloop, + me->mpoly, me->totpoly, + me->dvert, + do_verbose, do_fixes, + &changed); + + BLI_assert(changed == false); + + return is_valid; +} + +/** * Check all material indices of polygons are valid, invalid ones are set to 0. * \returns is_valid. */ diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index cb97cee4547..b49df101fe6 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -901,6 +901,19 @@ void modifier_deformVerts(struct ModifierData *md, const ModifierEvalContext *ct } } +void modifier_deformVerts_ensure_normals(struct ModifierData *md, const ModifierEvalContext *ctx, + struct Mesh *mesh, + float (*vertexCos)[3], int numVerts) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + BLI_assert(!mesh || CustomData_has_layer(&mesh->pdata, CD_NORMAL) == false); + + if (mesh && mti->dependsOnNormals && mti->dependsOnNormals(md)) { + BKE_mesh_calc_normals(mesh); + } + modifier_deformVerts(md, ctx, mesh, vertexCos, numVerts); +} + void modifier_deformMatrices(struct ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *mesh, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) @@ -993,6 +1006,18 @@ struct Mesh *modifier_applyModifier(struct ModifierData *md, const ModifierEvalC } } +struct Mesh *modifier_applyModifier_ensure_normals(struct ModifierData *md, const ModifierEvalContext *ctx, + struct Mesh *mesh) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + BLI_assert(CustomData_has_layer(&mesh->pdata, CD_NORMAL) == false); + + if (mti->dependsOnNormals && mti->dependsOnNormals(md)) { + BKE_mesh_calc_normals(mesh); + } + return modifier_applyModifier(md, ctx, mesh); +} + struct Mesh *modifier_applyModifierEM(struct ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData, struct Mesh *mesh) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 3b51ce9366f..d86b73ab1a9 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3473,6 +3473,7 @@ static void registerShaderNodes(void) register_node_type_sh_mix_rgb(); register_node_type_sh_valtorgb(); register_node_type_sh_rgbtobw(); + register_node_type_sh_shadertorgb(); register_node_type_sh_normal(); register_node_type_sh_mapping(); register_node_type_sh_curve_vec(); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 64eb6a44ce3..1e6d3041f3f 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -375,14 +375,12 @@ void BKE_object_free_caches(Object *object) for (md = object->modifiers.first; md != NULL; md = md->next) { if (md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; - if (psmd->dm_final != NULL) { - psmd->dm_final->needsFree = 1; - psmd->dm_final->release(psmd->dm_final); - psmd->dm_final = NULL; - if (psmd->dm_deformed != NULL) { - psmd->dm_deformed->needsFree = 1; - psmd->dm_deformed->release(psmd->dm_deformed); - psmd->dm_deformed = NULL; + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_deformed) { + BKE_id_free(NULL, psmd->mesh_deformed); + psmd->mesh_deformed = NULL; } psmd->flag |= eParticleSystemFlag_file_loaded; update_flag |= OB_RECALC_DATA; @@ -875,7 +873,7 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int f if (psys->clmd) { psysn->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth); modifier_copyData_ex((ModifierData *)psys->clmd, (ModifierData *)psysn->clmd, flag); - psys->hair_in_dm = psys->hair_out_dm = NULL; + psys->hair_in_mesh = psys->hair_out_mesh = NULL; } BLI_duplicatelist(&psysn->targets, &psys->targets); diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 70c5e4a18a1..4630bc14bf7 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -869,7 +869,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem if (!for_render) no_draw_flag |= PARS_NO_DISP; - ctime = BKE_scene_frame_get(scene); /* NOTE: in old animsys, used parent object's timeoffset... */ + ctime = DEG_get_ctime(ctx->depsgraph); /* NOTE: in old animsys, used parent object's timeoffset... */ totpart = psys->totpart; totchild = psys->totchild; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 8ed4164ab75..26c822f5fef 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -51,6 +51,7 @@ #include "BLI_noise.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_kdopbvh.h" #include "BLI_kdtree.h" #include "BLI_rand.h" #include "BLI_task.h" @@ -80,7 +81,7 @@ #include "BKE_library_remap.h" #include "BKE_modifier.h" #include "BKE_mesh.h" -#include "BKE_cdderivedmesh.h" +#include "BKE_cdderivedmesh.h" /* for weight_to_rgb() */ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_deform.h" @@ -110,7 +111,7 @@ void psys_init_rng(void) static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex); -static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, +static void get_cpa_texture(Mesh *mesh, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra); /* few helpers for countall etc. */ @@ -503,13 +504,13 @@ void free_hair(Object *UNUSED(ob), ParticleSystem *psys, int dynamics) } } - if (psys->hair_in_dm) - psys->hair_in_dm->release(psys->hair_in_dm); - psys->hair_in_dm = NULL; + if (psys->hair_in_mesh) + BKE_id_free(NULL, psys->hair_in_mesh); + psys->hair_in_mesh = NULL; - if (psys->hair_out_dm) - psys->hair_out_dm->release(psys->hair_out_dm); - psys->hair_out_dm = NULL; + if (psys->hair_out_mesh) + BKE_id_free(NULL, psys->hair_out_mesh); + psys->hair_out_mesh = NULL; } void free_keyed_keys(ParticleSystem *psys) { @@ -719,7 +720,7 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic typedef struct ParticleInterpolationData { HairKey *hkey[2]; - DerivedMesh *dm; + Mesh *mesh; MVert *mvert[2]; int keyed; @@ -853,8 +854,8 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic pind->birthtime = key->time; pind->dietime = (key + pa->totkey - 1)->time; - if (pind->dm) { - pind->mvert[0] = CDDM_get_vert(pind->dm, pa->hair_index); + if (pind->mesh) { + pind->mvert[0] = &pind->mesh->mvert[pa->hair_index]; pind->mvert[1] = pind->mvert[0] + 1; } } @@ -963,7 +964,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData edit_to_particle(keys + 1, pind->ekey[0]); edit_to_particle(keys + 2, pind->ekey[1]); } - else if (pind->dm) { + else if (pind->mesh) { pind->mvert[0] = pind->mvert[1] - 1; mvert_to_particle(keys + 1, pind->mvert[0], pind->hkey[0]); mvert_to_particle(keys + 2, pind->mvert[1], pind->hkey[1]); @@ -988,7 +989,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData else edit_to_particle(keys, pind->ekey[0]); } - else if (pind->dm) { + else if (pind->mesh) { if (pind->hkey[0] != pa->hair) mvert_to_particle(keys, pind->mvert[0] - 1, pind->hkey[0] - 1); else @@ -1007,7 +1008,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData else edit_to_particle(keys + 3, pind->ekey[1]); } - else if (pind->dm) { + else if (pind->mesh) { if (pind->hkey[1] != pa->hair + pa->totkey - 1) mvert_to_particle(keys + 3, pind->mvert[1] + 1, pind->hkey[1] + 1); else @@ -1233,7 +1234,7 @@ void psys_interpolate_mcol(const MCol *mcol, int quad, const float w[4], MCol *m } } -static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, const float fw[4], const float *values) +static float psys_interpolate_value_from_verts(Mesh *mesh, short from, int index, const float fw[4], const float *values) { if (values == 0 || index == -1) return 0.0; @@ -1244,7 +1245,7 @@ static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int case PART_FROM_FACE: case PART_FROM_VOLUME: { - MFace *mf = dm->getTessFaceData(dm, index, CD_MFACE); + MFace *mf = &mesh->mface[index]; return interpolate_particle_value(values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4); } @@ -1294,7 +1295,7 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4 * \return the DM tessface index. */ int psys_particle_dm_face_lookup( - DerivedMesh *dm_final, DerivedMesh *dm_deformed, + Mesh *mesh_final, Mesh *mesh_deformed, int findex_orig, const float fw[4], struct LinkNode **poly_nodes) { MFace *mtessface_final; @@ -1306,36 +1307,36 @@ int psys_particle_dm_face_lookup( const int *index_mf_to_mpoly = NULL; const int *index_mp_to_orig = NULL; - const int totface_final = dm_final->getNumTessFaces(dm_final); - const int totface_deformed = dm_deformed ? dm_deformed->getNumTessFaces(dm_deformed) : totface_final; + const int totface_final = mesh_final->totface; + const int totface_deformed = mesh_deformed ? mesh_deformed->totface : totface_final; if (ELEM(0, totface_final, totface_deformed)) { return DMCACHE_NOTFOUND; } - index_mf_to_mpoly = dm_final->getTessFaceDataArray(dm_final, CD_ORIGINDEX); - index_mp_to_orig = dm_final->getPolyDataArray(dm_final, CD_ORIGINDEX); + index_mf_to_mpoly = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX); + index_mp_to_orig = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX); BLI_assert(index_mf_to_mpoly); - if (dm_deformed) { - index_mf_to_mpoly_deformed = dm_deformed->getTessFaceDataArray(dm_deformed, CD_ORIGINDEX); + if (mesh_deformed) { + index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_deformed->fdata, CD_ORIGINDEX); } else { - BLI_assert(dm_final->deformedOnly); + BLI_assert(mesh_final->runtime.deformed_only); index_mf_to_mpoly_deformed = index_mf_to_mpoly; } BLI_assert(index_mf_to_mpoly_deformed); pindex_orig = index_mf_to_mpoly_deformed[findex_orig]; - if (dm_deformed == NULL) { - dm_deformed = dm_final; + if (mesh_deformed == NULL) { + mesh_deformed = mesh_final; } index_mf_to_mpoly_deformed = NULL; - mtessface_final = dm_final->getTessFaceArray(dm_final); - osface_final = dm_final->getTessFaceDataArray(dm_final, CD_ORIGSPACE); + mtessface_final = mesh_final->mface; + osface_final = CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE); if (osface_final == NULL) { /* Assume we don't need osface_final data, and we get a direct 1-1 mapping... */ @@ -1348,7 +1349,7 @@ int psys_particle_dm_face_lookup( return DMCACHE_NOTFOUND; } } - else if (findex_orig >= dm_deformed->getNumTessFaces(dm_deformed)) { + else if (findex_orig >= mesh_deformed->totface) { return DMCACHE_NOTFOUND; /* index not in the original mesh */ } @@ -1377,7 +1378,7 @@ int psys_particle_dm_face_lookup( else { /* if we have no node, try every face */ for (int findex_dst = 0; findex_dst < totface_final; findex_dst++) { /* If current tessface from 'final' DM and orig tessface (given by index) map to the same orig poly... */ - if (DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex_dst) == pindex_orig) { + if (BKE_mesh_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex_dst) == pindex_orig) { faceuv = osface_final[findex_dst].uv; /* check that this intersects - Its possible this misses :/ - @@ -1397,22 +1398,22 @@ int psys_particle_dm_face_lookup( return DMCACHE_NOTFOUND; } -static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float UNUSED(foffset), int *mapindex, float mapfw[4]) +static int psys_map_index_on_dm(Mesh *mesh, int from, int index, int index_dmcache, const float fw[4], float UNUSED(foffset), int *mapindex, float mapfw[4]) { if (index < 0) return 0; - if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) { + if (mesh->runtime.deformed_only || index_dmcache == DMCACHE_ISCHILD) { /* for meshes that are either only deformed or for child particles, the * index and fw do not require any mapping, so we can directly use it */ if (from == PART_FROM_VERT) { - if (index >= dm->getNumVerts(dm)) + if (index >= mesh->totvert) return 0; *mapindex = index; } else { /* FROM_FACE/FROM_VOLUME */ - if (index >= dm->getNumTessFaces(dm)) + if (index >= mesh->totface) return 0; *mapindex = index; @@ -1424,7 +1425,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ * to their new location, which means a different index, and for faces * also a new face interpolation weights */ if (from == PART_FROM_VERT) { - if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > dm->getNumVerts(dm)) + if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > mesh->totvert) return 0; *mapindex = index_dmcache; @@ -1437,15 +1438,15 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ i = index_dmcache; - if (i == DMCACHE_NOTFOUND || i >= dm->getNumTessFaces(dm)) + if (i == DMCACHE_NOTFOUND || i >= mesh->totface) return 0; *mapindex = i; /* modify the original weights to become * weights for the derived mesh face */ - osface = dm->getTessFaceDataArray(dm, CD_ORIGSPACE); - mface = dm->getTessFaceData(dm, i, CD_MFACE); + osface = CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE); + mface = &mesh->mface[i]; if (osface == NULL) mapfw[0] = mapfw[1] = mapfw[2] = mapfw[3] = 0.0f; @@ -1458,7 +1459,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ } /* interprets particle data to get a point on a mesh in object space */ -void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_dmcache, +void psys_particle_on_dm(Mesh *mesh_final, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3]) { @@ -1466,7 +1467,7 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d float (*orcodata)[3]; int mapindex; - if (!psys_map_index_on_dm(dm_final, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) { + if (!psys_map_index_on_dm(mesh_final, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) { if (vec) { vec[0] = vec[1] = vec[2] = 0.0; } if (nor) { nor[0] = nor[1] = 0.0; nor[2] = 1.0; } if (orco) { orco[0] = orco[1] = orco[2] = 0.0; } @@ -1476,13 +1477,13 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d return; } - orcodata = dm_final->getVertDataArray(dm_final, CD_ORCO); + orcodata = CustomData_get_layer(&mesh_final->vdata, CD_ORCO); if (from == PART_FROM_VERT) { - dm_final->getVertCo(dm_final, mapindex, vec); + copy_v3_v3(vec, mesh_final->mvert[mapindex].co); if (nor) { - dm_final->getVertNo(dm_final, mapindex, nor); + normal_short_to_float_v3(nor, mesh_final->mvert[mapindex].no); normalize_v3(nor); } @@ -1505,9 +1506,9 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d MTFace *mtface; MVert *mvert; - mface = dm_final->getTessFaceData(dm_final, mapindex, CD_MFACE); - mvert = dm_final->getVertDataArray(dm_final, CD_MVERT); - mtface = CustomData_get_layer(&dm_final->faceData, CD_MTFACE); + mface = &mesh_final->mface[mapindex]; + mvert = mesh_final->mvert; + mtface = mesh_final->mtface; if (mtface) mtface += mapindex; @@ -1526,15 +1527,15 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d } } -float psys_particle_value_from_verts(DerivedMesh *dm, short from, ParticleData *pa, float *values) +float psys_particle_value_from_verts(Mesh *mesh, short from, ParticleData *pa, float *values) { float mapfw[4]; int mapindex; - if (!psys_map_index_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, &mapindex, mapfw)) + if (!psys_map_index_on_dm(mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, &mapindex, mapfw)) return 0.0f; - return psys_interpolate_value_from_verts(dm, from, mapindex, mapfw, values); + return psys_interpolate_value_from_verts(mesh, from, mapindex, mapfw, values); } ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) @@ -1621,7 +1622,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3]) { - if (psmd && psmd->dm_final) { + if (psmd && psmd->mesh_final) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { if (vec) copy_v3_v3(vec, fuv); @@ -1631,7 +1632,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in return; } /* we cant use the num_dmcache */ - psys_particle_on_dm(psmd->dm_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); + psys_particle_on_dm(psmd->mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); } else psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco); @@ -1847,7 +1848,7 @@ static void offset_child(ChildParticle *cpa, ParticleKey *par, float *par_rot, P add_v3_v3(child->co, par->co); } -float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup) +float *psys_cache_vgroup(Mesh *mesh, ParticleSystem *psys, int vgroup) { float *vg = 0; @@ -1856,9 +1857,9 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup) } else if (psys->vgroup[vgroup]) { - MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + MDeformVert *dvert = mesh->dvert; if (dvert) { - int totvert = dm->getNumVerts(dm), i; + int totvert = mesh->totvert, i; vg = MEM_callocN(sizeof(float) * totvert, "vg_cache"); if (psys->vg_neg & (1 << vgroup)) { for (i = 0; i < totvert; i++) @@ -1898,7 +1899,7 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); /* Check if particle doesn't exist because of texture influence. Insert only existing particles into kdtree. */ - get_cpa_texture(sim->psmd->dm_final, psys, part, psys->particles + cpa->pa[0], p, cpa->num, cpa->fuv, orco, &ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra); + get_cpa_texture(sim->psmd->mesh_final, psys, part, psys->particles + cpa->pa[0], p, cpa->num, cpa->fuv, orco, &ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra); if (ptex.exist >= psys_frand(psys, p + 24)) { BLI_kdtree_insert(tree, p, orco); @@ -1973,15 +1974,15 @@ static bool psys_thread_context_init_path( psys->lattice_deform_data = psys_create_lattice_deform_data(&ctx->sim); /* cache all relevant vertex groups if they exist */ - ctx->vg_length = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_LENGTH); - ctx->vg_clump = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_CLUMP); - ctx->vg_kink = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_KINK); - ctx->vg_rough1 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH1); - ctx->vg_rough2 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH2); - ctx->vg_roughe = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGHE); - ctx->vg_twist = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_TWIST); + ctx->vg_length = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_LENGTH); + ctx->vg_clump = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_CLUMP); + ctx->vg_kink = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_KINK); + ctx->vg_rough1 = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGH1); + ctx->vg_rough2 = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGH2); + ctx->vg_roughe = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGHE); + ctx->vg_twist = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_TWIST); if (psys->part->flag & PART_CHILD_EFFECT) - ctx->vg_effector = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_EFFECTOR); + ctx->vg_effector = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_EFFECTOR); /* prepare curvemapping tables */ if ((part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && part->clumpcurve) { @@ -2133,7 +2134,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp for (w = 0; w < 4; w++) sub_v3_v3v3(off1[w], co, key[w]->co); - psys_mat_hair_to_global(ob, ctx->sim.psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); } else { ParticleData *pa = psys->particles + cpa->parent; @@ -2164,13 +2165,13 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp : pa->num_dmcache; /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */ - if (cpa_num > ctx->sim.psmd->dm_final->getNumTessFaces(ctx->sim.psmd->dm_final)) + if (cpa_num > ctx->sim.psmd->mesh_final->totface) cpa_num = 0; cpa_fuv = pa->fuv; psys_particle_on_emitter(ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco); - psys_mat_hair_to_global(ob, ctx->sim.psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); } child_keys->segments = ctx->segments; @@ -2420,7 +2421,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re ParticleSettings *part = psys->part; ParticleCacheKey *ca, **cache; - DerivedMesh *hair_dm = (psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) ? psys->hair_out_dm : NULL; + Mesh *hair_mesh = (psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) ? psys->hair_out_mesh : NULL; ParticleKey result; @@ -2465,15 +2466,15 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) { if ((psys->part->flag & PART_CHILD_EFFECT) == 0) - vg_effector = psys_cache_vgroup(psmd->dm_final, psys, PSYS_VG_EFFECTOR); + vg_effector = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_EFFECTOR); if (!psys->totchild) - vg_length = psys_cache_vgroup(psmd->dm_final, psys, PSYS_VG_LENGTH); + vg_length = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_LENGTH); } /* ensure we have tessfaces to be used for mapping */ if (part->from != PART_FROM_VERT) { - DM_ensure_tessface(psmd->dm_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); } /*---first main loop: create all actual particles' paths---*/ @@ -2482,14 +2483,14 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f); pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p)); if (vg_length) - pa_length *= psys_particle_value_from_verts(psmd->dm_final, part->from, pa, vg_length); + pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length); } pind.keyed = keyed; pind.cache = baked ? psys->pointcache : NULL; pind.epoint = NULL; pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); - pind.dm = hair_dm; + pind.mesh = hair_mesh; memset(cache[p], 0, sizeof(*cache[p]) * (segments + 1)); @@ -2499,7 +2500,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re init_particle_interpolation(sim->ob, sim->psys, pa, &pind); /* hairmat is needed for for non-hair particle too so we get proper rotations */ - psys_mat_hair_to_global(sim->ob, psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, psmd->mesh_final, psys->part->from, pa, hairmat); copy_v3_v3(rotmat[0], hairmat[2]); copy_v3_v3(rotmat[1], hairmat[1]); copy_v3_v3(rotmat[2], hairmat[0]); @@ -2531,7 +2532,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re /* dynamic hair is in object space */ /* keyed and baked are already in global space */ - if (hair_dm) + if (hair_mesh) mul_m4_v3(sim->ob->obmat, ca->co); else if (!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR)) mul_m4_v3(hairmat, ca->co); @@ -2554,7 +2555,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re if ((psys->part->flag & PART_CHILD_EFFECT) == 0) { float effector = 1.0f; if (vg_effector) - effector *= psys_particle_value_from_verts(psmd->dm_final, psys->part->from, pa, vg_effector); + effector *= psys_particle_value_from_verts(psmd->mesh_final, psys->part->from, pa, vg_effector); sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co); length = len_v3(vec); @@ -2691,7 +2692,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac pind.cache = NULL; pind.epoint = point; pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0; - pind.dm = NULL; + pind.mesh = NULL; /* should init_particle_interpolation set this ? */ @@ -2711,7 +2712,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac init_particle_interpolation(ob_eval, psys_eval, pa, &pind); if (psys_eval) { - psys_mat_hair_to_global(ob_eval, psmd_eval->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob_eval, psmd_eval->mesh_final, psys->part->from, pa, hairmat); copy_v3_v3(rotmat[0], hairmat[2]); copy_v3_v3(rotmat[1], hairmat[1]); copy_v3_v3(rotmat[2], hairmat[0]); @@ -2827,9 +2828,9 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac ParticleSimulationData sim = {0}; sim.depsgraph = depsgraph; sim.scene = scene; - sim.ob = ob; - sim.psys = psys; - sim.psmd = psys_get_modifier(ob, psys); + sim.ob = ob_eval; + sim.psys = psys_eval; + sim.psmd = psys_get_modifier(ob_eval, psys_eval); psys_cache_child_paths(&sim, cfra, true, use_render_params); } @@ -2919,7 +2920,7 @@ static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat cross_v3_v3v3(mat[0], mat[1], mat[2]); } -static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[4][4], int orco) +static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4][4], int orco) { float v[3][3]; MFace *mface; @@ -2927,72 +2928,72 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m float (*orcodata)[3]; int i = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num : pa->num_dmcache; - if (i == -1 || i >= dm->getNumTessFaces(dm)) { unit_m4(mat); return; } + if (i == -1 || i >= mesh->totface) { unit_m4(mat); return; } - mface = dm->getTessFaceData(dm, i, CD_MFACE); - osface = dm->getTessFaceData(dm, i, CD_ORIGSPACE); + mface = &mesh->mface[i]; + osface = CustomData_get(&mesh->fdata, i, CD_ORIGSPACE); - if (orco && (orcodata = dm->getVertDataArray(dm, CD_ORCO))) { + if (orco && (orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO))) { copy_v3_v3(v[0], orcodata[mface->v1]); copy_v3_v3(v[1], orcodata[mface->v2]); copy_v3_v3(v[2], orcodata[mface->v3]); /* ugly hack to use non-transformed orcos, since only those * give symmetric results for mirroring in particle mode */ - if (DM_get_vert_data_layer(dm, CD_ORIGINDEX)) + if (CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX)) BKE_mesh_orco_verts_transform(ob->data, v, 3, 1); } else { - dm->getVertCo(dm, mface->v1, v[0]); - dm->getVertCo(dm, mface->v2, v[1]); - dm->getVertCo(dm, mface->v3, v[2]); + copy_v3_v3(v[0], mesh->mvert[mface->v1].co); + copy_v3_v3(v[1], mesh->mvert[mface->v2].co); + copy_v3_v3(v[2], mesh->mvert[mface->v3].co); } triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat); } -void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) +void psys_mat_hair_to_object(Object *UNUSED(ob), Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4]) { float vec[3]; /* can happen when called from a different object's modifier */ - if (!dm) { + if (!mesh) { unit_m4(hairmat); return; } - psys_face_mat(0, dm, pa, hairmat, 0); - psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0); + psys_face_mat(0, mesh, pa, hairmat, 0); + psys_particle_on_dm(mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0); copy_v3_v3(hairmat[3], vec); } -void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) +void psys_mat_hair_to_orco(Object *ob, Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4]) { float vec[3], orco[3]; - psys_face_mat(ob, dm, pa, hairmat, 1); - psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco); + psys_face_mat(ob, mesh, pa, hairmat, 1); + psys_particle_on_dm(mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco); /* see psys_face_mat for why this function is called */ - if (DM_get_vert_data_layer(dm, CD_ORIGINDEX)) + if (CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX)) BKE_mesh_orco_verts_transform(ob->data, &orco, 1, 1); copy_v3_v3(hairmat[3], orco); } -void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float vec[3]) +void psys_vec_rot_to_face(Mesh *mesh, ParticleData *pa, float vec[3]) { float mat[4][4]; - psys_face_mat(0, dm, pa, mat, 0); + psys_face_mat(0, mesh, pa, mat, 0); transpose_m4(mat); /* cheap inverse for rotation matrix */ mul_mat3_m4_v3(mat, vec); } -void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) +void psys_mat_hair_to_global(Object *ob, Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4]) { float facemat[4][4]; - psys_mat_hair_to_object(ob, dm, from, pa, facemat); + psys_mat_hair_to_object(ob, mesh, from, pa, facemat); mul_m4_m4m4(hairmat, ob->obmat, facemat); } @@ -3274,25 +3275,25 @@ void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part, const /* Textures */ /************************************************/ -static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const float fuv[4], +static int get_particle_uv(Mesh *mesh, ParticleData *pa, int index, const float fuv[4], char *name, float *texco, bool from_vert) { MFace *mf; MTFace *tf; int i; - tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, name); + tf = CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name); if (tf == NULL) - tf = CustomData_get_layer(&dm->faceData, CD_MTFACE); + tf = mesh->mtface; if (tf == NULL) return 0; if (pa) { i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache; - if ((!from_vert && i >= dm->getNumTessFaces(dm)) || - (from_vert && i >= dm->getNumVerts(dm))) + if ((!from_vert && i >= mesh->totface) || + (from_vert && i >= mesh->totvert)) { i = -1; } @@ -3308,12 +3309,12 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const f } else { if (from_vert) { - mf = dm->getTessFaceDataArray(dm, CD_MFACE); + mf = mesh->mface; /* This finds the first face to contain the emitting vertex, * this is not ideal, but is mostly fine as UV seams generally * map to equal-colored parts of a texture */ - for (int j = 0; j < dm->getNumTessFaces(dm); j++, mf++) { + for (int j = 0; j < mesh->totface; j++, mf++) { if (ELEM(i, mf->v1, mf->v2, mf->v3, mf->v4)) { i = j; break; @@ -3321,7 +3322,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const f } } else { - mf = dm->getTessFaceData(dm, i, CD_MFACE); + mf = &mesh->mface[i]; } psys_interpolate_uvs(&tf[i], mf->v4, fuv, texco); @@ -3356,7 +3357,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const f CLAMP(pvalue, -1.0f, 1.0f); \ } (void)0 -static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra) +static void get_cpa_texture(Mesh *mesh, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra) { MTex *mtex, **mtexp = part->mtex; int m; @@ -3390,7 +3391,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti mul_m4_v3(mtex->object->imat, texvec); break; case TEXCO_UV: - if (fw && get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, + if (fw && get_particle_uv(mesh, NULL, face_index, fw, mtex->uvname, texvec, (part->from == PART_FROM_VERT))) { break; @@ -3468,7 +3469,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex mul_m4_v3(mtex->object->imat, texvec); break; case TEXCO_UV: - if (get_particle_uv(sim->psmd->dm_final, pa, 0, pa->fuv, mtex->uvname, + if (get_particle_uv(sim->psmd->mesh_final, pa, 0, pa->fuv, mtex->uvname, texvec, (part->from == PART_FROM_VERT))) { break; @@ -3598,28 +3599,28 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread ParticleSystem *psys = ctx->sim.psys; int i = cpa - psys->child; - get_cpa_texture(ctx->dm, psys, part, psys->particles + cpa->pa[0], i, cpa_num, cpa_fuv, orco, ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra); + get_cpa_texture(ctx->mesh, psys, part, psys->particles + cpa->pa[0], i, cpa_num, cpa_fuv, orco, ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra); if (ptex->exist < psys_frand(psys, i + 24)) return; if (ctx->vg_length) - ptex->length *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_length); + ptex->length *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_length); if (ctx->vg_clump) - ptex->clump *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_clump); + ptex->clump *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_clump); if (ctx->vg_kink) - ptex->kink_freq *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_kink); + ptex->kink_freq *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_kink); if (ctx->vg_rough1) - ptex->rough1 *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough1); + ptex->rough1 *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough1); if (ctx->vg_rough2) - ptex->rough2 *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough2); + ptex->rough2 *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough2); if (ctx->vg_roughe) - ptex->roughe *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe); + ptex->roughe *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe); if (ctx->vg_effector) - ptex->effector *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector); + ptex->effector *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector); if (ctx->vg_twist) - ptex->twist *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist); + ptex->twist *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist); } /* get's hair (or keyed) particles state at the "path time" specified in state->time */ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, const bool vel) @@ -3672,17 +3673,17 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); /* pind.dm disabled in editmode means we don't get effectors taken into * account when subdividing for instance */ - pind.dm = psys_in_edit_mode(sim->depsgraph, psys) ? NULL : psys->hair_out_dm; + pind.mesh = psys_in_edit_mode(sim->depsgraph, psys) ? NULL : psys->hair_out_mesh; /* XXX Sybren EEK */ init_particle_interpolation(sim->ob, psys, pa, &pind); do_particle_interpolation(psys, p, pa, t, &pind, state); - if (pind.dm) { + if (pind.mesh) { mul_m4_v3(sim->ob->obmat, state->co); mul_mat3_m4_v3(sim->ob->obmat, state->vel); } else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) { if ((pa->flag & PARS_REKEY) == 0) { - psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, part->from, pa, hairmat); mul_m4_v3(hairmat, state->co); mul_mat3_m4_v3(hairmat, state->vel); @@ -3749,7 +3750,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco); if (part->type == PART_HAIR) - psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); else unit_m4(hairmat); @@ -3770,7 +3771,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco); if (part->type == PART_HAIR) { psys_particle_on_emitter(psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco); - psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); } else { copy_v3_v3(orco, cpa->fuv); @@ -3789,7 +3790,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * /* get different child parameters from textures & vgroups */ memset(&ctx, 0, sizeof(ParticleThreadContext)); ctx.sim = *sim; - ctx.dm = psmd->dm_final; + ctx.mesh = psmd->mesh_final; ctx.ma = ma; /* TODO: assign vertex groups */ get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); @@ -3873,7 +3874,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta float timestep = psys_get_timestep(sim); /* negative time means "use current time" */ - cfra = state->time > 0 ? state->time : BKE_scene_frame_get(sim->scene); + cfra = state->time > 0 ? state->time : DEG_get_ctime(sim->depsgraph); if (p >= totpart) { if (!psys->totchild) @@ -4043,13 +4044,13 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT); if (cpa) { - if ((part->childtype == PART_CHILD_FACES) && (psmd->dm_final != NULL)) { - CustomData *mtf_data = psmd->dm_final->getTessFaceDataLayout(psmd->dm_final); + if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) { + CustomData *mtf_data = &psmd->mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); if (mtface && !is_grid) { - mface = psmd->dm_final->getTessFaceData(psmd->dm_final, cpa->num, CD_MFACE); + mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE); mtface += cpa->num; psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); } @@ -4062,8 +4063,8 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, } } - if ((part->from == PART_FROM_FACE) && (psmd->dm_final != NULL) && !is_grid) { - CustomData *mtf_data = psmd->dm_final->getTessFaceDataLayout(psmd->dm_final); + if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) { + CustomData *mtf_data = &psmd->mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); @@ -4072,14 +4073,14 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, if (num == DMCACHE_NOTFOUND) num = pa->num; - if (num >= psmd->dm_final->getNumTessFaces(psmd->dm_final)) { + if (num >= psmd->mesh_final->totface) { /* happens when simplify is enabled * gives invalid coords but would crash otherwise */ num = DMCACHE_NOTFOUND; } if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE); + mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE); mtface += num; psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); } @@ -4255,7 +4256,7 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par float hairmat[4][4], imat[4][4]; for (p = 0; p < psys->totpart; p++, pa++) { - psys_mat_hair_to_global(sim.ob, sim.psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); hkey = pa->hair; diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index bf21e18f4b9..e85a3f15022 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -50,9 +50,8 @@ #include "DNA_particle_types.h" #include "DNA_scene_types.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_DerivedMesh.h" #include "BKE_global.h" +#include "BKE_library.h" #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_particle.h" @@ -80,7 +79,7 @@ static void alloc_child_particles(ParticleSystem *psys, int tot) } } -static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, DerivedMesh *deformdm, ParticleSystem *psys, const bool use_render_params) +static void distribute_simple_children(Scene *scene, Object *ob, Mesh *final_mesh, Mesh *deform_mesh, ParticleSystem *psys, const bool use_render_params) { ChildParticle *cpa = NULL; int i, p; @@ -107,14 +106,14 @@ static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *fi } } /* dmcache must be updated for parent particles if children from faces is used */ - psys_calc_dmcache(ob, finaldm, deformdm, psys); + psys_calc_dmcache(ob, final_mesh, deform_mesh, psys); } -static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys) +static void distribute_grid(Mesh *mesh, ParticleSystem *psys) { ParticleData *pa=NULL; float min[3], max[3], delta[3], d; - MVert *mv, *mvert = dm->getVertDataArray(dm,0); - int totvert=dm->getNumVerts(dm), from=psys->part->from; + MVert *mv, *mvert = mesh->mvert; + int totvert=mesh->totvert, from=psys->part->from; int i, j, k, p, res=psys->part->grid_res, size[3], axis; /* find bounding box of dm */ @@ -196,8 +195,8 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys) int a, a1, a2, a0mul, a1mul, a2mul, totface; int amax= from==PART_FROM_FACE ? 3 : 1; - totface=dm->getNumTessFaces(dm); - mface=mface_array=dm->getTessFaceDataArray(dm,CD_MFACE); + totface = mesh->totface; + mface = mface_array = mesh->mface; for (a=0; a<amax; a++) { if (a==0) { a0mul=res*res; a1mul=res; a2mul=1; } @@ -440,7 +439,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i ParticleThreadContext *ctx= thread->ctx; MFace *mface; - mface = ctx->dm->getTessFaceDataArray(ctx->dm, CD_MFACE); + mface = ctx->mesh->mface; int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */ @@ -449,12 +448,12 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i zero_v4(pa->fuv); - if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->dm->getNumVerts(ctx->dm)) { + if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->mesh->totvert) { /* This finds the first face to contain the emitting vertex, * this is not ideal, but is mostly fine as UV seams generally * map to equal-colored parts of a texture */ - for (int i = 0; i < ctx->dm->getNumTessFaces(ctx->dm); i++, mface++) { + for (int i = 0; i < ctx->mesh->totface; i++, mface++) { if (ELEM(pa->num, mface->v1, mface->v2, mface->v3, mface->v4)) { unsigned int *vert = &mface->v1; @@ -475,7 +474,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i KDTreeNearest ptn[3]; int w, maxw; - psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0); + psys_particle_on_dm(ctx->mesh,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0); BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1); maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3); @@ -491,7 +490,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, int p) { ParticleThreadContext *ctx= thread->ctx; - DerivedMesh *dm= ctx->dm; + Mesh *mesh = ctx->mesh; float randu, randv; int distr= ctx->distr; int i; @@ -500,7 +499,7 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i MFace *mface; pa->num = i = ctx->index[p]; - mface = dm->getTessFaceData(dm,i,CD_MFACE); + mface = &mesh->mface[i]; switch (distr) { case PART_DISTR_JIT: @@ -533,7 +532,7 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, int p) { ParticleThreadContext *ctx= thread->ctx; - DerivedMesh *dm= ctx->dm; + Mesh *mesh = ctx->mesh; float *v1, *v2, *v3, *v4, nor[3], co[3]; float cur_d, min_d, randu, randv; int distr= ctx->distr; @@ -541,10 +540,10 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */ MFace *mface; - MVert *mvert=dm->getVertDataArray(dm,CD_MVERT); + MVert *mvert = mesh->mvert; pa->num = i = ctx->index[p]; - mface = dm->getTessFaceData(dm,i,CD_MFACE); + mface = &mesh->mface[i]; switch (distr) { case PART_DISTR_JIT: @@ -572,7 +571,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, pa->foffset= 0.0f; /* experimental */ - tot=dm->getNumTessFaces(dm); + tot = mesh->totface; psys_interpolate_face(mvert,mface,0,0,pa->fuv,co,nor,0,0,0); @@ -582,7 +581,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, min_d=FLT_MAX; intersect=0; - for (i=0,mface=dm->getTessFaceDataArray(dm,CD_MFACE); i<tot; i++,mface++) { + for (i=0, mface=mesh->mface; i<tot; i++,mface++) { if (i==pa->num) continue; v1=mvert[mface->v1].co; @@ -628,7 +627,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, int p) { ParticleThreadContext *ctx= thread->ctx; Object *ob= ctx->sim.ob; - DerivedMesh *dm= ctx->dm; + Mesh *mesh = ctx->mesh; float orco1[3], co1[3], nor1[3]; float randu, randv; int cfrom= ctx->cfrom; @@ -644,7 +643,7 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i return; } - mf= dm->getTessFaceData(dm, ctx->index[p], CD_MFACE); + mf = &mesh->mface[ctx->index[p]]; randu= BLI_rng_get_float(thread->rng); randv= BLI_rng_get_float(thread->rng); @@ -661,7 +660,7 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i int parent[10]; float pweight[10]; - psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1); + psys_particle_on_dm(mesh,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1); BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1); maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3); @@ -800,19 +799,18 @@ static void distribute_invalid(ParticleSimulationData *sim, int from) } } -/* Creates a distribution of coordinates on a DerivedMesh */ -/* This is to denote functionality that does not yet work with mesh - only derived mesh */ +/* Creates a distribution of coordinates on a Mesh */ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, ParticleSimulationData *sim, int from) { Scene *scene = sim->scene; - DerivedMesh *finaldm = sim->psmd->dm_final; + Mesh *final_mesh = sim->psmd->mesh_final; Object *ob = sim->ob; ParticleSystem *psys= sim->psys; ParticleData *pa=0, *tpars= 0; ParticleSettings *part; ParticleSeam *seams= 0; KDTree *tree=0; - DerivedMesh *dm= NULL; + Mesh *mesh = NULL; float *jit= NULL; int i, p=0; int cfrom=0; @@ -829,7 +827,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti if (totpart==0) return 0; - if (!finaldm->deformedOnly && !finaldm->getTessFaceDataArray(finaldm, CD_ORIGINDEX)) { + if (!final_mesh->runtime.deformed_only && !CustomData_get_layer(&final_mesh->fdata, CD_ORIGINDEX)) { printf("Can't create particles with the current modifier stack, disable destructive modifiers\n"); // XXX error("Can't paint with the current modifier stack, disable destructive modifiers"); return 0; @@ -849,7 +847,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti /* Simple children */ if (part->childtype != PART_CHILD_FACES) { BLI_srandom(31415926 + psys->seed + psys->child_seed); - distribute_simple_children(scene, ob, finaldm, sim->psmd->dm_deformed, psys, use_render_params); + distribute_simple_children(scene, ob, final_mesh, sim->psmd->mesh_deformed, psys, use_render_params); return 0; } } @@ -859,17 +857,23 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti BLI_srandom(31415926 + psys->seed); if (psys->part->use_modifier_stack) { - dm = finaldm; + mesh = final_mesh; } else { - dm = CDDM_from_mesh((Mesh*)ob->data); + BKE_id_copy_ex( + NULL, ob->data, (ID **)&mesh, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); } - DM_ensure_tessface(dm); + BKE_mesh_tessface_ensure(mesh); - distribute_grid(dm,psys); + distribute_grid(mesh,psys); - if (dm != finaldm) { - dm->release(dm); + if (mesh != final_mesh) { + BKE_id_free(NULL, mesh); } return 0; @@ -880,17 +884,17 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti if (from == PART_FROM_CHILD) { distr=PART_DISTR_RAND; BLI_srandom(31415926 + psys->seed + psys->child_seed); - dm= finaldm; + mesh= final_mesh; /* BMESH ONLY */ - DM_ensure_tessface(dm); + BKE_mesh_tessface_ensure(mesh); children=1; tree=BLI_kdtree_new(totpart); for (p=0,pa=psys->particles; p<totpart; p++,pa++) { - psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco); + psys_particle_on_dm(mesh,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco); BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco, 1, 1); BLI_kdtree_insert(tree, p, orco); } @@ -905,20 +909,26 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti BLI_srandom(31415926 + psys->seed); if (psys->part->use_modifier_stack) - dm = finaldm; + mesh = final_mesh; else - dm= CDDM_from_mesh((Mesh*)ob->data); + BKE_id_copy_ex( + NULL, ob->data, (ID **)&mesh, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); - DM_ensure_tessface(dm); + BKE_mesh_tessface_ensure(mesh); /* we need orco for consistent distributions */ - if (!CustomData_has_layer(&dm->vertData, CD_ORCO)) - DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob)); + if (!CustomData_has_layer(&mesh->vdata, CD_ORCO)) + CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob), mesh->totvert); if (from == PART_FROM_VERT) { - MVert *mv= dm->getVertDataArray(dm, CD_MVERT); - float (*orcodata)[3] = dm->getVertDataArray(dm, CD_ORCO); - int totvert = dm->getNumVerts(dm); + MVert *mv = mesh->mvert; + float (*orcodata)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO); + int totvert = mesh->totvert; tree=BLI_kdtree_new(totvert); @@ -937,7 +947,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti } /* Get total number of emission elements and allocate needed arrays */ - totelem = (from == PART_FROM_VERT) ? dm->getNumVerts(dm) : dm->getNumTessFaces(dm); + totelem = (from == PART_FROM_VERT) ? mesh->totvert : mesh->totface; if (totelem == 0) { distribute_invalid(sim, children ? PART_FROM_CHILD : 0); @@ -945,7 +955,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti if (G.debug & G_DEBUG) fprintf(stderr,"Particle distribution error: Nothing to emit from!\n"); - if (dm != finaldm) dm->release(dm); + if (mesh != final_mesh) BKE_id_free(NULL, mesh); BLI_kdtree_free(tree); @@ -962,10 +972,10 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti float totarea=0.f, co1[3], co2[3], co3[3], co4[3]; float (*orcodata)[3]; - orcodata= dm->getVertDataArray(dm, CD_ORCO); + orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO); for (i=0; i<totelem; i++) { - MFace *mf=dm->getTessFaceData(dm,i,CD_MFACE); + MFace *mf = &mesh->mface[i]; if (orcodata) { copy_v3_v3(co1, orcodata[mf->v1]); @@ -980,14 +990,14 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti } } else { - v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT); - v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT); - v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT); + v1 = &mesh->mvert[mf->v1]; + v2 = &mesh->mvert[mf->v2]; + v3 = &mesh->mvert[mf->v3]; copy_v3_v3(co1, v1->co); copy_v3_v3(co2, v2->co); copy_v3_v3(co3, v3->co); if (mf->v4) { - v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT); + v4 = &mesh->mvert[mf->v4]; copy_v3_v3(co4, v4->co); } } @@ -1014,7 +1024,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti } /* Calculate weights from vgroup */ - vweight = psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY); + vweight = psys_cache_vgroup(mesh,psys,PSYS_VG_DENSITY); if (vweight) { if (from==PART_FROM_VERT) { @@ -1023,7 +1033,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti } else { /* PART_FROM_FACE / PART_FROM_VOLUME */ for (i=0;i<totelem; i++) { - MFace *mf=dm->getTessFaceData(dm,i,CD_MFACE); + MFace *mf = &mesh->mface[i]; tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3]; if (mf->v4) { @@ -1126,12 +1136,12 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti int *orig_index = NULL; if (from == PART_FROM_VERT) { - if (dm->numVertData) - orig_index = dm->getVertDataArray(dm, CD_ORIGINDEX); + if (mesh->totvert) + orig_index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX); } else { - if (dm->numTessFaceData) - orig_index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + if (mesh->totface) + orig_index = CustomData_get_layer(&mesh->fdata, CD_ORIGINDEX); } if (orig_index) { @@ -1174,7 +1184,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti ctx->maxweight= maxweight; ctx->cfrom= cfrom; ctx->distr= distr; - ctx->dm= dm; + ctx->mesh= mesh; ctx->tpars= tpars; if (children) { @@ -1198,7 +1208,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) TaskPool *task_pool; ParticleThreadContext ctx; ParticleTask *tasks; - DerivedMesh *finaldm = sim->psmd->dm_final; + Mesh *final_mesh = sim->psmd->mesh_final; int i, totpart, numtasks; /* create a task pool for distribution tasks */ @@ -1223,10 +1233,10 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) BLI_task_pool_free(task_pool); - psys_calc_dmcache(sim->ob, finaldm, sim->psmd->dm_deformed, sim->psys); + psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_deformed, sim->psys); - if (ctx.dm != finaldm) - ctx.dm->release(ctx.dm); + if (ctx.mesh != final_mesh) + BKE_id_free(NULL, ctx.mesh); psys_tasks_free(tasks, numtasks); @@ -1247,7 +1257,7 @@ void distribute_particles(ParticleSimulationData *sim, int from) int distr_error=0; if (psmd) { - if (psmd->dm_final) + if (psmd->mesh_final) distribute_particles_on_dm(sim, from); else distr_error=1; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 74348246da2..ff61faf9cd2 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -74,6 +74,7 @@ #include "BKE_collision.h" #include "BKE_colortools.h" #include "BKE_effect.h" +#include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_particle.h" @@ -310,7 +311,7 @@ int psys_get_tot_child(Scene *scene, ParticleSystem *psys, const bool use_render /* Distribution */ /************************************************/ -void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deformed, ParticleSystem *psys) +void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_deformed, ParticleSystem *psys) { /* use for building derived mesh mapping info: * @@ -323,13 +324,13 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform PARTICLE_P; /* CACHE LOCATIONS */ - if (!dm_final->deformedOnly) { + if (!mesh_final->runtime.deformed_only) { /* Will use later to speed up subsurf/derivedmesh */ LinkNode *node, *nodedmelem, **nodearray; int totdmelem, totelem, i, *origindex, *origindex_poly = NULL; if (psys->part->from == PART_FROM_VERT) { - totdmelem= dm_final->getNumVerts(dm_final); + totdmelem = mesh_final->totvert; if (use_modifier_stack) { totelem= totdmelem; @@ -337,11 +338,11 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform } else { totelem= me->totvert; - origindex= dm_final->getVertDataArray(dm_final, CD_ORIGINDEX); + origindex = CustomData_get_layer(&mesh_final->vdata, CD_ORIGINDEX); } } else { /* FROM_FACE/FROM_VOLUME */ - totdmelem= dm_final->getNumTessFaces(dm_final); + totdmelem= mesh_final->totface; if (use_modifier_stack) { totelem= totdmelem; @@ -349,11 +350,11 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform origindex_poly= NULL; } else { - totelem = dm_deformed->getNumTessFaces(dm_deformed); - origindex = dm_final->getTessFaceDataArray(dm_final, CD_ORIGINDEX); + totelem = mesh_deformed->totface; + origindex = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX); /* for face lookups we need the poly origindex too */ - origindex_poly= dm_final->getPolyDataArray(dm_final, CD_ORIGINDEX); + origindex_poly = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX); if (origindex_poly == NULL) { origindex= NULL; } @@ -413,7 +414,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform pa->num_dmcache = DMCACHE_NOTFOUND; } else { /* FROM_FACE/FROM_VOLUME */ - pa->num_dmcache = psys_particle_dm_face_lookup(dm_final, dm_deformed, pa->num, pa->fuv, nodearray); + pa->num_dmcache = psys_particle_dm_face_lookup(mesh_final, mesh_deformed, pa->num, pa->fuv, nodearray); } } } @@ -437,7 +438,7 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData { memset(ctx, 0, sizeof(ParticleThreadContext)); ctx->sim = *sim; - ctx->dm = ctx->sim.psmd->dm_final; + ctx->mesh = ctx->sim.psmd->mesh_final; ctx->ma = give_current_material(sim->ob, sim->psys->part->omat); } @@ -3022,11 +3023,11 @@ static MDeformVert *hair_set_pinning(MDeformVert *dvert, float weight) return dvert; } -static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int totedge, DerivedMesh **r_dm, ClothHairData **r_hairdata) +static void hair_create_input_mesh(ParticleSimulationData *sim, int totpoint, int totedge, Mesh **r_mesh, ClothHairData **r_hairdata) { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; - DerivedMesh *dm; + Mesh *mesh; ClothHairData *hairdata; MVert *mvert; MEdge *medge; @@ -3038,14 +3039,14 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int float max_length; float hair_radius; - dm = *r_dm; - if (!dm) { - *r_dm = dm = CDDM_new(totpoint, totedge, 0, 0, 0); - DM_add_vert_layer(dm, CD_MDEFORMVERT, CD_CALLOC, NULL); - } - mvert = CDDM_get_verts(dm); - medge = CDDM_get_edges(dm); - dvert = DM_get_vert_data_layer(dm, CD_MDEFORMVERT); + mesh = *r_mesh; + if (!mesh) { + *r_mesh = mesh = BKE_mesh_new_nomain(totpoint, totedge, 0, 0, 0); + CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, mesh->totvert); + } + mvert = mesh->mvert; + medge = mesh->medge; + dvert = mesh->dvert; hairdata = *r_hairdata; if (!hairdata) { @@ -3080,7 +3081,7 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int pa->hair_index = hair_index; use_hair = psys_hair_use_simulation(pa, max_length); - psys_mat_hair_to_object(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_object(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat); normalize_m4(root_mat); @@ -3177,26 +3178,26 @@ static void do_hair_dynamics(ParticleSimulationData *sim) } realloc_roots = false; /* whether hair root info array has to be reallocated */ - if (psys->hair_in_dm) { - DerivedMesh *dm = psys->hair_in_dm; - if (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm)) { - dm->release(dm); - psys->hair_in_dm = NULL; + if (psys->hair_in_mesh) { + Mesh *mesh = psys->hair_in_mesh; + if (totpoint != mesh->totvert || totedge != mesh->totedge) { + BKE_id_free(NULL, mesh); + psys->hair_in_mesh = NULL; realloc_roots = true; } } - if (!psys->hair_in_dm || !psys->clmd->hairdata || realloc_roots) { + if (!psys->hair_in_mesh || !psys->clmd->hairdata || realloc_roots) { if (psys->clmd->hairdata) { MEM_freeN(psys->clmd->hairdata); psys->clmd->hairdata = NULL; } } - hair_create_input_dm(sim, totpoint, totedge, &psys->hair_in_dm, &psys->clmd->hairdata); + hair_create_input_mesh(sim, totpoint, totedge, &psys->hair_in_mesh, &psys->clmd->hairdata); - if (psys->hair_out_dm) - psys->hair_out_dm->release(psys->hair_out_dm); + if (psys->hair_out_mesh) + BKE_id_free(NULL, psys->hair_out_mesh); psys->clmd->point_cache = psys->pointcache; /* for hair sim we replace the internal cloth effector weights temporarily @@ -3205,13 +3206,22 @@ static void do_hair_dynamics(ParticleSimulationData *sim) clmd_effweights = psys->clmd->sim_parms->effector_weights; psys->clmd->sim_parms->effector_weights = psys->part->effector_weights; - deformedVerts = MEM_mallocN(sizeof(*deformedVerts) * psys->hair_in_dm->getNumVerts(psys->hair_in_dm), "do_hair_dynamics vertexCos"); - psys->hair_out_dm = CDDM_copy(psys->hair_in_dm); - psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts); - - clothModifier_do(psys->clmd, sim->depsgraph, sim->scene, sim->ob, psys->hair_in_dm, deformedVerts); - - CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts); + BKE_id_copy_ex( + NULL, &psys->hair_in_mesh->id, (ID **)&psys->hair_out_mesh, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); + deformedVerts = BKE_mesh_vertexCos_get(psys->hair_out_mesh, NULL); + + /* TODO(Sybren): after porting Cloth modifier, remove this conversion */ + DerivedMesh *hair_in_dm = CDDM_from_mesh(psys->hair_in_mesh); + clothModifier_do(psys->clmd, sim->depsgraph, sim->scene, sim->ob, hair_in_dm, deformedVerts); + hair_in_dm->needsFree = 1; + hair_in_dm->release(hair_in_dm); + + BKE_mesh_apply_vert_coords(psys->hair_out_mesh, deformedVerts); MEM_freeN(deformedVerts); @@ -3238,7 +3248,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re if (psys->recalc & PSYS_RECALC_RESET) { /* need this for changing subsurf levels */ - psys_calc_dmcache(sim->ob, sim->psmd->dm_final, sim->psmd->dm_deformed, psys); + psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_deformed, psys); if (psys->clmd) cloth_free_modifier(psys->clmd); @@ -3285,7 +3295,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) if (pa->totkey) { sub_v3_v3(key->co, root->co); - psys_vec_rot_to_face(sim->psmd->dm_final, pa, key->co); + psys_vec_rot_to_face(sim->psmd->mesh_final, pa, key->co); } key->time = pa->state.time; @@ -4221,7 +4231,7 @@ void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *o if (!psys_check_enabled(ob, psys, use_render_params)) return; - cfra= BKE_scene_frame_get(scene); + cfra = DEG_get_ctime(depsgraph); sim.depsgraph = depsgraph; sim.scene = scene; @@ -4237,11 +4247,11 @@ void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *o return; } - if (!sim.psmd->dm_final) + if (!sim.psmd->mesh_final) return; if (part->from != PART_FROM_VERT) { - DM_ensure_tessface(sim.psmd->dm_final); + BKE_mesh_tessface_ensure(sim.psmd->mesh_final); } /* execute drivers only, as animation has already been done */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b810ff0b393..ea0498930ff 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -248,8 +248,7 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons sce_dst->master_collection = BKE_collection_copy_master(bmain, sce_src->master_collection, flag); } - /* layers */ - IDPropertyTemplate val = {0}; + /* View Layers */ BLI_duplicatelist(&sce_dst->view_layers, &sce_src->view_layers); for (ViewLayer *view_layer_src = sce_src->view_layers.first, *view_layer_dst = sce_dst->view_layers.first; view_layer_src; @@ -258,15 +257,6 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons BKE_view_layer_copy_data(sce_dst, sce_src, view_layer_dst, view_layer_src, flag_subdata); } - sce_dst->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - if (sce_src->collection_properties) { - IDP_MergeGroup_ex(sce_dst->collection_properties, sce_src->collection_properties, true, flag_subdata); - } - sce_dst->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - if (sce_src->layer_properties) { - IDP_MergeGroup_ex(sce_dst->layer_properties, sce_src->layer_properties, true, flag_subdata); - } - BLI_duplicatelist(&(sce_dst->markers), &(sce_src->markers)); BLI_duplicatelist(&(sce_dst->transform_spaces), &(sce_src->transform_spaces)); BLI_duplicatelist(&(sce_dst->r.views), &(sce_src->r.views)); @@ -526,19 +516,8 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user) sce->master_collection = NULL; } - /* LayerCollection engine settings. */ - if (sce->collection_properties) { - IDP_FreeProperty(sce->collection_properties); - MEM_freeN(sce->collection_properties); - sce->collection_properties = NULL; - } - - /* Render engine setting. */ - if (sce->layer_properties) { - IDP_FreeProperty(sce->layer_properties); - MEM_freeN(sce->layer_properties); - sce->layer_properties = NULL; - } + /* These are freed on doversion. */ + BLI_assert(sce->layer_properties == NULL); } void BKE_scene_free(Scene *sce) @@ -818,19 +797,76 @@ void BKE_scene_init(Scene *sce) /* Master Collection */ sce->master_collection = BKE_collection_master_add(); - /* Engine settings */ - IDPropertyTemplate val = {0}; - sce->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - BKE_layer_collection_engine_settings_create(sce->collection_properties); - - sce->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP); - BKE_view_layer_engine_settings_create(sce->layer_properties); - BKE_view_layer_add(sce, "View Layer"); /* SceneDisplay */ copy_v3_v3(sce->display.light_direction, (float[3]){-M_SQRT1_3, -M_SQRT1_3, M_SQRT1_3}); sce->display.shadow_shift = 0.1; + + sce->display.matcap_icon = 1; + sce->display.matcap_type = CLAY_MATCAP_NONE; + sce->display.matcap_hue = 0.5f; + sce->display.matcap_saturation = 0.5f; + sce->display.matcap_value = 0.5f; + sce->display.matcap_ssao_distance = 0.2f; + sce->display.matcap_ssao_attenuation = 1.0f; + sce->display.matcap_ssao_factor_cavity = 1.0f; + sce->display.matcap_ssao_factor_edge = 1.0f; + sce->display.matcap_ssao_samples = 16; + + /* SceneEEVEE */ + sce->eevee.gi_diffuse_bounces = 3; + sce->eevee.gi_cubemap_resolution = 512; + sce->eevee.gi_visibility_resolution = 32; + + sce->eevee.taa_samples = 16; + sce->eevee.taa_render_samples = 64; + + sce->eevee.sss_samples = 7; + sce->eevee.sss_jitter_threshold = 0.3f; + + sce->eevee.ssr_quality = 0.25f; + sce->eevee.ssr_max_roughness = 0.5f; + sce->eevee.ssr_thickness = 0.2f; + sce->eevee.ssr_border_fade = 0.075f; + sce->eevee.ssr_firefly_fac = 10.0f; + + sce->eevee.volumetric_start = 0.1f; + sce->eevee.volumetric_end = 100.0f; + sce->eevee.volumetric_tile_size = 8; + sce->eevee.volumetric_samples = 64; + sce->eevee.volumetric_sample_distribution = 0.8f; + sce->eevee.volumetric_light_clamp = 0.0f; + sce->eevee.volumetric_shadow_samples = 16; + + sce->eevee.gtao_distance = 0.2f; + sce->eevee.gtao_factor = 1.0f; + sce->eevee.gtao_quality = 0.25f; + + sce->eevee.bokeh_max_size = 100.0f; + sce->eevee.bokeh_threshold = 1.0f; + + copy_v3_fl(sce->eevee.bloom_color, 1.0f); + sce->eevee.bloom_threshold = 0.8f; + sce->eevee.bloom_knee = 0.5f; + sce->eevee.bloom_intensity = 0.8f; + sce->eevee.bloom_radius = 6.5f; + sce->eevee.bloom_clamp = 1.0f; + + sce->eevee.motion_blur_samples = 8; + sce->eevee.motion_blur_shutter = 1.0f; + + sce->eevee.shadow_method = SHADOW_ESM; + sce->eevee.shadow_cube_size = 512; + sce->eevee.shadow_cascade_size = 1024; + + sce->eevee.flag = + SCE_EEVEE_VOLUMETRIC_LIGHTS | + SCE_EEVEE_VOLUMETRIC_COLORED | + SCE_EEVEE_GTAO_BENT_NORMALS | + SCE_EEVEE_GTAO_BOUNCE | + SCE_EEVEE_TAA_REPROJECTION | + SCE_EEVEE_SSR_HALF_RESOLUTION; } Scene *BKE_scene_add(Main *bmain, const char *name) diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index f0db054620a..baecbd90bc5 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -40,6 +40,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_path_util.h" +#include "BLI_rand.h" #include "BLI_string.h" #include "DNA_listBase.h" @@ -54,7 +55,8 @@ static ListBase studiolights; #define STUDIO_LIGHT_EXTENSIONS ".jpg", ".hdr" #define STUDIO_LIGHT_DIFFUSE_SAMPLE_STEP 64 -static const char *STUDIO_LIGHT_FOLDER = "studiolights/"; +static const char *STUDIO_LIGHT_CAMERA_FOLDER = "studiolights/camera/"; +static const char *STUDIO_LIGHT_WORLD_FOLDER = "studiolights/world/"; /* FUNCTIONS */ static void studiolight_free(struct StudioLight *sl) @@ -79,6 +81,16 @@ static void direction_to_equirectangular(float r[2], const float dir[3]) r[1] = (acosf(dir[2] / 1.0) - M_PI) / -M_PI; } +static void equirectangular_to_direction(float r[3], float u, float v) +{ + float phi = (-(M_PI * 2))*u + M_PI; + float theta = -M_PI*v + M_PI; + float sin_theta = sinf(theta); + r[0] = sin_theta*cosf(phi); + r[1] = sin_theta*sinf(phi); + r[2] = cosf(theta); +} + static void studiolight_calculate_directional_diffuse_light(ImBuf *ibuf, float color[4], const float start[3], const float v1[3], const float v2[3]) { const int steps = STUDIO_LIGHT_DIFFUSE_SAMPLE_STEP; @@ -125,18 +137,18 @@ static void studiolight_calculate_diffuse_light(StudioLight *sl) copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 0.0f); copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_NEG], 0.0f); - if (sl->flag &= STUDIOLIGHT_EXTERNAL_FILE) { + if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) { ImBuf* ibuf = NULL; ibuf = IMB_loadiffname(sl->path, 0, NULL); if (ibuf) { IMB_float_from_rect(ibuf); - + /* XXX: should calculate the same, only rendering should be different */ copy_v3_fl3(start, -1.0f, -1.0f, -1.0f); copy_v3_fl3(v1, 0.0f, 2.0f, 0.0f); copy_v3_fl3(v2, 0.0f, 0.0f, 2.0f); - studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Z_NEG], start, v1, v2); + studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Y_POS], start, v1, v2); copy_v3_fl3(start, 1.0f, -1.0f, -1.0f); - studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Z_POS], start, v1, v2); + studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Y_NEG], start, v1, v2); copy_v3_fl3(start, -1.0f, -1.0f, -1.0f); copy_v3_fl3(v1, 2.0f, 0.0f, 0.0f); @@ -145,41 +157,58 @@ static void studiolight_calculate_diffuse_light(StudioLight *sl) copy_v3_fl3(start, -1.0f, 1.0f, -1.0f); studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_X_NEG], start, v1, v2); - copy_v3_fl3(start, -1.0f, -1.0f, -1.0f); + copy_v3_fl3(start, -1.0f, -1.0f, 1.0f); copy_v3_fl3(v1, 2.0f, 0.0f, 0.0f); copy_v3_fl3(v2, 0.0f, 2.0f, 0.0f); - studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Y_NEG], start, v1, v2); - copy_v3_fl3(start, -1.0f, -1.0f, 1.0f); - studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Y_POS], start, v1, v2); - + studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Z_POS], start, v1, v2); + copy_v3_fl3(start, -1.0f, -1.0f, -1.0f); + studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Z_NEG], start, v1, v2); IMB_freeImBuf(ibuf); } } sl->flag |= STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED; } +static void studiolight_calculate_light_direction(StudioLight *sl) +{ + float best_light = 0.0; + sl->light_direction[0] = 0.0f; + sl->light_direction[1] = 0.0f; + sl->light_direction[2] = -1.0f; -/* API */ -void BKE_studiolight_init(void) + if ((sl->flag & STUDIOLIGHT_EXTERNAL_FILE) && (sl->flag & STUDIOLIGHT_ORIENTATION_WORLD)) { + ImBuf* ibuf = NULL; + ibuf = IMB_loadiffname(sl->path, 0, NULL); + if (ibuf) { + IMB_float_from_rect(ibuf); + /* go over every pixel, determine light, if higher calc direction off the light */ + float col[4]; + float direction[3]; + float new_light; + for (int y = 0; y < ibuf->y; y ++) { + for (int x = 0; x < ibuf->x; x ++) { + nearest_interpolation_color_wrap(ibuf, NULL, col, x, y); + new_light = col[0] + col[1] + col[2]; + if (new_light > best_light) { + equirectangular_to_direction(direction, x, y); + sl->light_direction[0] = direction[1]; + sl->light_direction[1] = direction[2]; + sl->light_direction[2] = direction[0]; + best_light = new_light; + } + } + } + IMB_freeImBuf(ibuf); + } + } + sl->flag |= STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED; +} + +static void studiolight_add_files_from_datafolder(const int folder_id, const char* subfolder, int flag) { StudioLight *sl; - /* go over the preset folder and add a studiolight for every image with its path */ - /* order studio lights by name */ - /* Also reserve icon space for it. */ - /* Add default studio light */ - sl = studiolight_create(); - BLI_strncpy(sl->name, "INTERNAL_01\0", FILE_MAXFILE); - sl->flag = STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED; - copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_POS], 0.0f); - copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_NEG], 0.0f); - copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_POS], 0.0f); - copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_NEG], 0.0f); - copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 1.0f); - copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_NEG], 0.0f); - BLI_addtail(&studiolights, sl); - struct direntry *dir; - const char *folder = BKE_appdir_folder_id(BLENDER_DATAFILES, STUDIO_LIGHT_FOLDER); + const char *folder = BKE_appdir_folder_id(folder_id, subfolder); if (folder) { unsigned int totfile = BLI_filelist_dir_contents(folder, &dir); int i; @@ -189,7 +218,7 @@ void BKE_studiolight_init(void) const char *path = dir[i].path; if (BLI_testextensie_n(filename, STUDIO_LIGHT_EXTENSIONS, NULL)) { sl = studiolight_create(); - sl->flag = STUDIOLIGHT_EXTERNAL_FILE; + sl->flag = STUDIOLIGHT_EXTERNAL_FILE | flag; BLI_strncpy(sl->name, filename, FILE_MAXFILE); BLI_strncpy(sl->path, path, FILE_MAXFILE); BLI_addtail(&studiolights, sl); @@ -199,6 +228,63 @@ void BKE_studiolight_init(void) BLI_filelist_free(dir, totfile); dir = NULL; } + +} + +static int studiolight_flag_cmp_order(const StudioLight *sl) +{ + /* Internal studiolights before external studio lights */ + if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) { + return 1; + } + return 0; +} + +static int studiolight_cmp(const void *a, const void *b) +{ + const StudioLight *sl1 = a; + const StudioLight *sl2 = b; + + const int flagorder1 = studiolight_flag_cmp_order(sl1); + const int flagorder2 = studiolight_flag_cmp_order(sl2); + + if (flagorder1 < flagorder2){ + return -1; + } + else if (flagorder1 > flagorder2) + { + return 1; + } + else { + return BLI_strcasecmp(sl1->name, sl2->name); + } +} +/* API */ +void BKE_studiolight_init(void) +{ + StudioLight *sl; + /* go over the preset folder and add a studiolight for every image with its path */ + /* order studio lights by name */ + /* Also reserve icon space for it. */ + /* Add default studio light */ + sl = studiolight_create(); + BLI_strncpy(sl->name, "INTERNAL_01", FILE_MAXFILE); + sl->flag = STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA; + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_POS], 0.0f); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_NEG], 0.0f); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_POS], 1.0f); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_NEG], 0.0f); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 0.0f); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_NEG], 0.0f); + BLI_addtail(&studiolights, sl); + + studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIO_LIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA); + studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIO_LIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA); + studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIO_LIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD); + studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIO_LIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD); + + /* sort studio lights on filename. */ + BLI_listbase_sort(&studiolights, studiolight_cmp); } void BKE_studiolight_free(void) @@ -274,9 +360,9 @@ unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size) float color[3]; mul_v3_v3fl(color, sl->diffuse_light[STUDIOLIGHT_X_POS], clamp_f(normal[0], 0.0, 1.0)); interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_X_NEG], clamp_f(-normal[0], 0.0, 1.0)); - interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_POS], clamp_f(normal[1], 0.0, 1.0)); - interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_NEG], clamp_f(-normal[1], 0.0, 1.0)); - interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_POS], clamp_f(normal[2], 0.0, 1.0)); + interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_POS], clamp_f(normal[1], 0.0, 1.0)); + interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_NEG], clamp_f(-normal[1], 0.0, 1.0)); + interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_POS], clamp_f(normal[2], 0.0, 1.0)); pixelresult = rgb_to_cpack( linearrgb_to_srgb(color[0]), @@ -291,11 +377,14 @@ unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size) void BKE_studiolight_ensure_flag(StudioLight *sl, int flag) { - if (sl->flag & flag){ + if ((sl->flag & flag) == flag){ return; } if ((flag & STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED)) { studiolight_calculate_diffuse_light(sl); } + if ((flag & STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED)) { + studiolight_calculate_light_direction(sl); + } } diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 76c3b6ef3fd..e7cbe05d713 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -107,6 +107,7 @@ typedef void (*BVHTree_RangeQuery)(void *userdata, int index, const float co[3], typedef void (*BVHTree_NearestProjectedCallback)( void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest); diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 111450b6402..f12ee2b3c69 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -315,6 +315,11 @@ bool isect_ray_seg_v2( const float v0[2], const float v1[2], float *r_lambda, float *r_u); +bool isect_ray_seg_v3( + const float ray_origin[3], const float ray_direction[3], + const float v0[3], const float v1[3], + float *r_lambda); + /* point in polygon */ bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr, const bool use_holes); bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr, const bool use_holes); diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 5571636be63..b3adf3106c1 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -2040,7 +2040,10 @@ static void bvhtree_nearest_projected_dfs_recursive( { if (node->totnode == 0) { if (data->callback) { - data->callback(data->userdata, node->index, &data->precalc, &data->nearest); + data->callback( + data->userdata, node->index, &data->precalc, + NULL, 0, + &data->nearest); } else { data->nearest.index = node->index; @@ -2089,7 +2092,10 @@ static void bvhtree_nearest_projected_with_clipplane_test_dfs_recursive( { if (node->totnode == 0) { if (data->callback) { - data->callback(data->userdata, node->index, &data->precalc, &data->nearest); + data->callback( + data->userdata, node->index, &data->precalc, + data->clip_plane, data->clip_plane_len, + &data->nearest); } else { data->nearest.index = node->index; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 0e7358aa426..a72cbb67883 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -570,6 +570,8 @@ float dist_squared_to_ray_v3( *r_depth = dot_v3v3(dvec, ray_direction); return len_squared_v3(dvec) - SQUARE(*r_depth); } + + /** * Find the closest point in a seg to a ray and return the distance squared. * \param r_point: Is the point on segment closest to ray (or to ray_origin if the ray and the segment are parallel). @@ -580,45 +582,38 @@ float dist_squared_ray_to_seg_v3( const float v0[3], const float v1[3], float r_point[3], float *r_depth) { - float a[3], t[3], n[3], lambda; - sub_v3_v3v3(a, v1, v0); - sub_v3_v3v3(t, v0, ray_origin); - cross_v3_v3v3(n, a, ray_direction); - const float nlen = len_squared_v3(n); - - /* if (nlen == 0.0f) the lines are parallel, - * has no nearest point, only distance squared.*/ - if (nlen == 0.0f) { - /* Calculate the distance to the point v0 then */ - copy_v3_v3(r_point, v0); - *r_depth = dot_v3v3(t, ray_direction); - } - else { - float c[3], cray[3]; - sub_v3_v3v3(c, n, t); - cross_v3_v3v3(cray, c, ray_direction); - lambda = dot_v3v3(cray, n) / nlen; - if (lambda <= 0) { + float lambda, depth; + if (isect_ray_seg_v3( + ray_origin, ray_direction, v0, v1, &lambda)) + { + if (lambda <= 0.0f) { copy_v3_v3(r_point, v0); - - *r_depth = dot_v3v3(t, ray_direction); } - else if (lambda >= 1) { + else if (lambda >= 1.0f) { copy_v3_v3(r_point, v1); - - sub_v3_v3v3(t, v1, ray_origin); - *r_depth = dot_v3v3(t, ray_direction); } else { - madd_v3_v3v3fl(r_point, v0, a, lambda); - - sub_v3_v3v3(t, r_point, ray_origin); - *r_depth = dot_v3v3(t, ray_direction); + interp_v3_v3v3(r_point, v0, v1, lambda); } } - return len_squared_v3(t) - SQUARE(*r_depth); + else { + /* has no nearest point, only distance squared. */ + /* Calculate the distance to the point v0 then */ + copy_v3_v3(r_point, v0); + } + + float dvec[3]; + sub_v3_v3v3(dvec, r_point, ray_origin); + depth = dot_v3v3(dvec, ray_direction); + + if (r_depth) { + *r_depth = depth; + } + + return len_squared_v3(dvec) - SQUARE(depth); } + /* Returns the coordinates of the nearest vertex and * the farthest vertex from a plane (or normal). */ void aabb_get_near_far_from_plane( @@ -1986,6 +1981,33 @@ bool isect_ray_seg_v2( return false; } + +bool isect_ray_seg_v3( + const float ray_origin[3], const float ray_direction[3], + const float v0[3], const float v1[3], + float *r_lambda) +{ + float a[3], t[3], n[3]; + sub_v3_v3v3(a, v1, v0); + sub_v3_v3v3(t, v0, ray_origin); + cross_v3_v3v3(n, a, ray_direction); + const float nlen = len_squared_v3(n); + + if (nlen == 0.0f) { + /* the lines are parallel.*/ + return false; + } + + float c[3], cray[3]; + sub_v3_v3v3(c, n, t); + cross_v3_v3v3(cray, c, ray_direction); + + *r_lambda = dot_v3v3(cray, n) / nlen; + + return true; +} + + /** * Check if a point is behind all planes. */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ccc3e2dea74..035df228da4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4465,7 +4465,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) psys->clmd->sim_parms->presets = 0; } - psys->hair_in_dm = psys->hair_out_dm = NULL; + psys->hair_in_mesh = psys->hair_out_mesh = NULL; psys->clmd->solver_result = NULL; } @@ -5222,8 +5222,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) else if (md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - psmd->dm_final = NULL; - psmd->dm_deformed = NULL; + psmd->mesh_final = NULL; + psmd->mesh_deformed = NULL; psmd->psys= newdataadr(fd, psmd->psys); psmd->flag &= ~eParticleSystemFlag_psys_updated; psmd->flag |= eParticleSystemFlag_file_loaded; @@ -5578,8 +5578,6 @@ static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer) link_list(fd, &(view_layer->freestyle_config.modules)); link_list(fd, &(view_layer->freestyle_config.linesets)); - view_layer->properties_evaluated = NULL; - BLI_listbase_clear(&view_layer->drawdata); view_layer->object_bases_array = NULL; view_layer->object_bases_hash = NULL; @@ -6344,15 +6342,9 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain) direct_link_view_layer(fd, view_layer); } - sce->collection_properties = newdataadr(fd, sce->collection_properties); - IDP_DirectLinkGroup_OrFree(&sce->collection_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); - sce->layer_properties = newdataadr(fd, sce->layer_properties); IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); - BKE_layer_collection_engine_settings_validate_scene(sce); - BKE_view_layer_engine_settings_validate_scene(sce); - direct_link_workspace_link_scene_data(fd, sce, &bmain->workspaces); } diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index badebda0b38..8e0795f7e34 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -2267,7 +2267,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) SO_SCENES, SO_LIBRARIES, SO_SEQUENCE, - SO_DATABLOCKS)) + SO_DATA_API)) { so->outlinevis = SO_SCENES; } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index db483160655..b69e75a107c 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -702,7 +702,7 @@ void do_versions_after_linking_280(Main *main) if (space->spacetype == SPACE_OUTLINER) { SpaceOops *soutliner = (SpaceOops *)space; - soutliner->outlinevis = SO_COLLECTIONS; + soutliner->outlinevis = SO_VIEW_LAYER; if (BLI_listbase_count_at_most(&layer->layer_collections, 2) == 1) { if (soutliner->treestore == NULL) { @@ -1032,11 +1032,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) SO_SCENES, SO_LIBRARIES, SO_SEQUENCE, - SO_DATABLOCKS, - SO_ID_ORPHANS, - SO_COLLECTIONS)) + SO_DATA_API, + SO_ID_ORPHANS)) { - so->outlinevis = SO_COLLECTIONS; + so->outlinevis = SO_VIEW_LAYER; } } } @@ -1252,5 +1251,215 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) scene->toolsettings->transform_pivot_point = V3D_AROUND_CENTER_MEAN; } } + + if (!DNA_struct_find(fd->filesdna, "SceneEEVEE")) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + /* First set the default for all the properties. */ + + scene->eevee.gi_diffuse_bounces = 3; + scene->eevee.gi_cubemap_resolution = 512; + scene->eevee.gi_visibility_resolution = 32; + + scene->eevee.taa_samples = 16; + scene->eevee.taa_render_samples = 64; + + scene->eevee.sss_samples = 7; + scene->eevee.sss_jitter_threshold = 0.3f; + + scene->eevee.ssr_quality = 0.25f; + scene->eevee.ssr_max_roughness = 0.5f; + scene->eevee.ssr_thickness = 0.2f; + scene->eevee.ssr_border_fade = 0.075f; + scene->eevee.ssr_firefly_fac = 10.0f; + + scene->eevee.volumetric_start = 0.1f; + scene->eevee.volumetric_end = 100.0f; + scene->eevee.volumetric_tile_size = 8; + scene->eevee.volumetric_samples = 64; + scene->eevee.volumetric_sample_distribution = 0.8f; + scene->eevee.volumetric_light_clamp = 0.0f; + scene->eevee.volumetric_shadow_samples = 16; + + scene->eevee.gtao_distance = 0.2f; + scene->eevee.gtao_factor = 1.0f; + scene->eevee.gtao_quality = 0.25f; + + scene->eevee.bokeh_max_size = 100.0f; + scene->eevee.bokeh_threshold = 1.0f; + + copy_v3_fl(scene->eevee.bloom_color, 1.0f); + scene->eevee.bloom_threshold = 0.8f; + scene->eevee.bloom_knee = 0.5f; + scene->eevee.bloom_intensity = 0.8f; + scene->eevee.bloom_radius = 6.5f; + scene->eevee.bloom_clamp = 1.0f; + + scene->eevee.motion_blur_samples = 8; + scene->eevee.motion_blur_shutter = 1.0f; + + scene->eevee.shadow_method = SHADOW_ESM; + scene->eevee.shadow_cube_size = 512; + scene->eevee.shadow_cascade_size = 1024; + + scene->eevee.flag = + SCE_EEVEE_VOLUMETRIC_LIGHTS | + SCE_EEVEE_VOLUMETRIC_COLORED | + SCE_EEVEE_GTAO_BENT_NORMALS | + SCE_EEVEE_GTAO_BOUNCE | + SCE_EEVEE_TAA_REPROJECTION | + SCE_EEVEE_SSR_HALF_RESOLUTION; + + + /* If the file is pre-2.80 move on. */ + if (scene->layer_properties == NULL) { + continue; + } + + /* Now we handle eventual properties that may be set in the file. */ +#define EEVEE_GET_BOOL(_props, _name, _flag) \ + { \ + IDProperty *_idprop = IDP_GetPropertyFromGroup(_props, #_name); \ + if (_idprop != NULL) { \ + const int _value = IDP_Int(_idprop); \ + if (_value) { \ + scene->eevee.flag |= _flag; \ + } \ + else { \ + scene->eevee.flag &= ~_flag; \ + } \ + } \ + } + +#define EEVEE_GET_INT(_props, _name) \ + { \ + IDProperty *_idprop = IDP_GetPropertyFromGroup(_props, #_name); \ + if (_idprop != NULL) { \ + scene->eevee._name = IDP_Int(_idprop); \ + } \ + } + +#define EEVEE_GET_FLOAT(_props, _name) \ + { \ + IDProperty *_idprop = IDP_GetPropertyFromGroup(_props, #_name); \ + if (_idprop != NULL) { \ + scene->eevee._name = IDP_Float(_idprop); \ + } \ + } + +#define EEVEE_GET_FLOAT_ARRAY(_props, _name, _length) \ + { \ + IDProperty *_idprop = IDP_GetPropertyFromGroup(_props, #_name); \ + if (_idprop != NULL) { \ + const float *_values = IDP_Array(_idprop); \ + for (int _i = 0; _i < _length; _i++) { \ + scene->eevee._name [_i] = _values[_i]; \ + } \ + } \ + } + + IDProperty *props = IDP_GetPropertyFromGroup(scene->layer_properties, RE_engine_id_BLENDER_EEVEE); + EEVEE_GET_BOOL(props, volumetric_enable, SCE_EEVEE_VOLUMETRIC_ENABLED); + EEVEE_GET_BOOL(props, volumetric_lights, SCE_EEVEE_VOLUMETRIC_LIGHTS); + EEVEE_GET_BOOL(props, volumetric_shadows, SCE_EEVEE_VOLUMETRIC_SHADOWS); + EEVEE_GET_BOOL(props, volumetric_colored_transmittance, SCE_EEVEE_VOLUMETRIC_COLORED); + EEVEE_GET_BOOL(props, gtao_enable, SCE_EEVEE_GTAO_ENABLED); + EEVEE_GET_BOOL(props, gtao_use_bent_normals, SCE_EEVEE_GTAO_BENT_NORMALS); + EEVEE_GET_BOOL(props, gtao_bounce, SCE_EEVEE_GTAO_BOUNCE); + EEVEE_GET_BOOL(props, dof_enable, SCE_EEVEE_DOF_ENABLED); + EEVEE_GET_BOOL(props, bloom_enable, SCE_EEVEE_BLOOM_ENABLED); + EEVEE_GET_BOOL(props, motion_blur_enable, SCE_EEVEE_MOTION_BLUR_ENABLED); + EEVEE_GET_BOOL(props, shadow_high_bitdepth, SCE_EEVEE_SHADOW_HIGH_BITDEPTH); + EEVEE_GET_BOOL(props, taa_reprojection, SCE_EEVEE_TAA_REPROJECTION); + EEVEE_GET_BOOL(props, sss_enable, SCE_EEVEE_SSS_ENABLED); + EEVEE_GET_BOOL(props, sss_separate_albedo, SCE_EEVEE_SSS_SEPARATE_ALBEDO); + EEVEE_GET_BOOL(props, ssr_enable, SCE_EEVEE_SSR_ENABLED); + EEVEE_GET_BOOL(props, ssr_refraction, SCE_EEVEE_SSR_REFRACTION); + EEVEE_GET_BOOL(props, ssr_halfres, SCE_EEVEE_SSR_HALF_RESOLUTION); + + EEVEE_GET_INT(props, gi_diffuse_bounces); + EEVEE_GET_INT(props, gi_diffuse_bounces); + EEVEE_GET_INT(props, gi_cubemap_resolution); + EEVEE_GET_INT(props, gi_visibility_resolution); + + EEVEE_GET_INT(props, taa_samples); + EEVEE_GET_INT(props, taa_render_samples); + + EEVEE_GET_INT(props, sss_samples); + EEVEE_GET_FLOAT(props, sss_jitter_threshold); + + EEVEE_GET_FLOAT(props, ssr_quality); + EEVEE_GET_FLOAT(props, ssr_max_roughness); + EEVEE_GET_FLOAT(props, ssr_thickness); + EEVEE_GET_FLOAT(props, ssr_border_fade); + EEVEE_GET_FLOAT(props, ssr_firefly_fac); + + EEVEE_GET_FLOAT(props, volumetric_start); + EEVEE_GET_FLOAT(props, volumetric_end); + EEVEE_GET_INT(props, volumetric_tile_size); + EEVEE_GET_INT(props, volumetric_samples); + EEVEE_GET_FLOAT(props, volumetric_sample_distribution); + EEVEE_GET_FLOAT(props, volumetric_light_clamp); + EEVEE_GET_INT(props, volumetric_shadow_samples); + + EEVEE_GET_FLOAT(props, gtao_distance); + EEVEE_GET_FLOAT(props, gtao_factor); + EEVEE_GET_FLOAT(props, gtao_quality); + + EEVEE_GET_FLOAT(props, bokeh_max_size); + EEVEE_GET_FLOAT(props, bokeh_threshold); + + EEVEE_GET_FLOAT_ARRAY(props, bloom_color, 3); + EEVEE_GET_FLOAT(props, bloom_threshold); + EEVEE_GET_FLOAT(props, bloom_knee); + EEVEE_GET_FLOAT(props, bloom_intensity); + EEVEE_GET_FLOAT(props, bloom_radius); + EEVEE_GET_FLOAT(props, bloom_clamp); + + EEVEE_GET_INT(props, motion_blur_samples); + EEVEE_GET_FLOAT(props, motion_blur_shutter); + + EEVEE_GET_INT(props, shadow_method); + EEVEE_GET_INT(props, shadow_cube_size); + EEVEE_GET_INT(props, shadow_cascade_size); + + /* Cleanup. */ + IDP_FreeProperty(scene->layer_properties); + MEM_freeN(scene->layer_properties); + scene->layer_properties = NULL; + +#undef EEVEE_GET_FLOAT_ARRAY +#undef EEVEE_GET_FLOAT +#undef EEVEE_GET_INT +#undef EEVEE_GET_BOOL + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "SceneDisplay", "int", "matcap_icon")) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + scene->display.matcap_icon = 1; + scene->display.matcap_type = CLAY_MATCAP_NONE; + scene->display.matcap_hue = 0.5f; + scene->display.matcap_saturation = 0.5f; + scene->display.matcap_value = 0.5f; + scene->display.matcap_ssao_distance = 0.2f; + scene->display.matcap_ssao_attenuation = 1.0f; + scene->display.matcap_ssao_factor_cavity = 1.0f; + scene->display.matcap_ssao_factor_edge = 1.0f; + scene->display.matcap_ssao_samples = 16; + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "SpaceOops", "short", "filter_id_type")) { + for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_OUTLINER) { + SpaceOops *soops = (SpaceOops *)sl; + soops->filter_id_type = ID_GR; + } + } + } + } + } } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index dd8f1955a38..ec3c5289532 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2640,18 +2640,13 @@ static void write_scene(WriteData *wd, Scene *sce) write_view_layer(wd, view_layer); } - if (sce->layer_properties) { - IDP_WriteProperty(sce->layer_properties, wd); - } - - if (sce->collection_properties) { - IDP_WriteProperty(sce->collection_properties, wd); - } - if (sce->master_collection) { writestruct(wd, DATA, Collection, 1, sce->master_collection); write_collection_nolib(wd, sce->master_collection); } + + /* Freed on doversion. */ + BLI_assert(sce->layer_properties == NULL); } static void write_gpencil(WriteData *wd, bGPdata *gpd) diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index 1a1a3bd7af4..76407d057a2 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -245,7 +245,7 @@ DrawEngineType draw_engine_basic_type = { RenderEngineType DRW_engine_viewport_basic_type = { NULL, NULL, BASIC_ENGINE, N_("Basic"), RE_INTERNAL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, &draw_engine_basic_type, {NULL, NULL, NULL} }; diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c index 78d2d7b344c..8731fd7cdcf 100644 --- a/source/blender/draw/engines/clay/clay_engine.c +++ b/source/blender/draw/engines/clay/clay_engine.c @@ -41,6 +41,8 @@ #include "DRW_render.h" +#include "DEG_depsgraph_query.h" + #include "clay_engine.h" #ifdef WITH_CLAY_ENGINE @@ -273,7 +275,7 @@ static struct GPUTexture *load_matcaps(PreviewImage *prv[24], int nbr) static int matcap_to_index(int matcap) { - return (int)matcap - (int)ICON_MATCAP_01; + return matcap - 1; } /* Using Hammersley distribution */ @@ -437,10 +439,8 @@ static void clay_engine_init(void *vedata) /* SSAO setup */ { const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get( - view_layer, RE_engine_id_BLENDER_CLAY); - int ssao_samples = BKE_collection_engine_property_value_get_int(props, "ssao_samples"); + Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); + const int ssao_samples = scene_eval->display.matcap_ssao_samples; float invproj[4][4]; float dfdyfacs[2]; @@ -639,18 +639,17 @@ static int hair_mat_in_ubo(CLAY_Storage *storage, const CLAY_HAIR_UBO_Material * static void ubo_mat_from_object(CLAY_Storage *storage, Object *UNUSED(ob), bool *r_needs_ao, int *r_id) { const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_CLAY); - - int matcap_icon = BKE_collection_engine_property_value_get_int(props, "matcap_icon"); - float matcap_rot = BKE_collection_engine_property_value_get_float(props, "matcap_rotation"); - float matcap_hue = BKE_collection_engine_property_value_get_float(props, "matcap_hue"); - float matcap_sat = BKE_collection_engine_property_value_get_float(props, "matcap_saturation"); - float matcap_val = BKE_collection_engine_property_value_get_float(props, "matcap_value"); - float ssao_distance = BKE_collection_engine_property_value_get_float(props, "ssao_distance"); - float ssao_factor_cavity = BKE_collection_engine_property_value_get_float(props, "ssao_factor_cavity"); - float ssao_factor_edge = BKE_collection_engine_property_value_get_float(props, "ssao_factor_edge"); - float ssao_attenuation = BKE_collection_engine_property_value_get_float(props, "ssao_attenuation"); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); + + const int matcap_icon = scene_eval->display.matcap_icon; + const float matcap_rot = scene_eval->display.matcap_rotation; + const float matcap_hue = scene_eval->display.matcap_hue; + const float matcap_sat = scene_eval->display.matcap_saturation; + const float matcap_val = scene_eval->display.matcap_value; + const float ssao_distance = scene_eval->display.matcap_ssao_distance; + const float ssao_factor_cavity = scene_eval->display.matcap_ssao_factor_cavity; + const float ssao_factor_edge = scene_eval->display.matcap_ssao_factor_edge; + const float ssao_attenuation = scene_eval->display.matcap_ssao_attenuation; CLAY_UBO_Material r_ubo = {{0.0f}}; @@ -683,15 +682,14 @@ static void ubo_mat_from_object(CLAY_Storage *storage, Object *UNUSED(ob), bool static void hair_ubo_mat_from_object(Object *UNUSED(ob), CLAY_HAIR_UBO_Material *r_ubo) { const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_CLAY); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - int matcap_icon = BKE_collection_engine_property_value_get_int(props, "matcap_icon"); - float matcap_rot = BKE_collection_engine_property_value_get_float(props, "matcap_rotation"); - float matcap_hue = BKE_collection_engine_property_value_get_float(props, "matcap_hue"); - float matcap_sat = BKE_collection_engine_property_value_get_float(props, "matcap_saturation"); - float matcap_val = BKE_collection_engine_property_value_get_float(props, "matcap_value"); - float hair_randomness = BKE_collection_engine_property_value_get_float(props, "hair_brightness_randomness"); + const int matcap_icon = scene_eval->display.matcap_icon; + const float matcap_rot = scene_eval->display.matcap_rotation; + const float matcap_hue = scene_eval->display.matcap_hue; + const float matcap_sat = scene_eval->display.matcap_saturation; + const float matcap_val = scene_eval->display.matcap_value; + const float hair_randomness = scene_eval->display.matcap_hair_brightness_randomness; memset(r_ubo, 0x0, sizeof(*r_ubo)); @@ -940,34 +938,6 @@ static void clay_draw_scene(void *vedata) } } -static void clay_layer_collection_settings_create(RenderEngine *UNUSED(engine), IDProperty *props) -{ - BLI_assert(props && - props->type == IDP_GROUP && - props->subtype == IDP_GROUP_SUB_ENGINE_RENDER); - - BKE_collection_engine_property_add_int(props, "matcap_icon", ICON_MATCAP_01); - BKE_collection_engine_property_add_int(props, "type", CLAY_MATCAP_NONE); - BKE_collection_engine_property_add_float(props, "matcap_rotation", 0.0f); - BKE_collection_engine_property_add_float(props, "matcap_hue", 0.5f); - BKE_collection_engine_property_add_float(props, "matcap_saturation", 0.5f); - BKE_collection_engine_property_add_float(props, "matcap_value", 0.5f); - BKE_collection_engine_property_add_float(props, "ssao_distance", 0.2f); - BKE_collection_engine_property_add_float(props, "ssao_attenuation", 1.0f); - BKE_collection_engine_property_add_float(props, "ssao_factor_cavity", 1.0f); - BKE_collection_engine_property_add_float(props, "ssao_factor_edge", 1.0f); - BKE_collection_engine_property_add_float(props, "hair_brightness_randomness", 0.0f); -} - -static void clay_view_layer_settings_create(RenderEngine *UNUSED(engine), IDProperty *props) -{ - BLI_assert(props && - props->type == IDP_GROUP && - props->subtype == IDP_GROUP_SUB_ENGINE_RENDER); - - BKE_collection_engine_property_add_int(props, "ssao_samples", 16); -} - static void clay_engine_free(void) { DRW_SHADER_FREE_SAFE(e_data.clay_sh); @@ -1003,8 +973,6 @@ RenderEngineType DRW_engine_viewport_clay_type = { NULL, NULL, CLAY_ENGINE, N_("Clay"), RE_INTERNAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - &clay_layer_collection_settings_create, - &clay_view_layer_settings_create, &draw_engine_clay_type, {NULL, NULL, NULL} }; diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c index 2b0cdf846b4..f644b59c0b7 100644 --- a/source/blender/draw/engines/eevee/eevee_bloom.c +++ b/source/blender/draw/engines/eevee/eevee_bloom.c @@ -31,10 +31,13 @@ #include "BKE_global.h" /* for G.debug_value */ -#include "eevee_private.h" #include "GPU_extensions.h" #include "GPU_texture.h" +#include "DEG_depsgraph_query.h" + +#include "eevee_private.h" + static struct { /* Bloom */ struct GPUShader *bloom_blit_sh[2]; @@ -87,10 +90,9 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) EEVEE_EffectsInfo *effects = stl->effects; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if (BKE_collection_engine_property_value_get_bool(props, "bloom_enable")) { + if (scene_eval->flag & SCE_EEVEE_BLOOM_ENABLED) { const float *viewport_size = DRW_viewport_size_get(); /* Shaders */ @@ -120,12 +122,12 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) }); /* Parameters */ - float threshold = BKE_collection_engine_property_value_get_float(props, "bloom_threshold"); - float knee = BKE_collection_engine_property_value_get_float(props, "bloom_knee"); - float intensity = BKE_collection_engine_property_value_get_float(props, "bloom_intensity"); - const float *color = BKE_collection_engine_property_value_get_float_array(props, "bloom_color"); - float radius = BKE_collection_engine_property_value_get_float(props, "bloom_radius"); - effects->bloom_clamp = BKE_collection_engine_property_value_get_float(props, "bloom_clamp"); + const float threshold = scene_eval->eevee.bloom_threshold; + const float knee = scene_eval->eevee.bloom_knee; + const float intensity = scene_eval->eevee.bloom_intensity; + const float *color = scene_eval->eevee.bloom_color; + const float radius = scene_eval->eevee.bloom_radius; + effects->bloom_clamp = scene_eval->eevee.bloom_clamp; /* determine the iteration count */ const float minDim = (float)MIN2(blitsize[0], blitsize[1]); diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c index 1ba9b5f9de4..c275a5005ff 100644 --- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c +++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c @@ -82,11 +82,9 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v EEVEE_EffectsInfo *effects = stl->effects; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if (BKE_collection_engine_property_value_get_bool(props, "dof_enable")) { - Scene *scene = draw_ctx->scene; + if (scene_eval->flag & SCE_EEVEE_DOF_ENABLED) { RegionView3D *rv3d = draw_ctx->rv3d; if (!e_data.dof_downsample_sh) { @@ -141,7 +139,7 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though * because the shader reads coordinates in world space, which is in blender units. * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */ - float scale = (scene->unit.system) ? scene->unit.scale_length : 1.0f; + float scale = (scene_eval->unit.system) ? scene_eval->unit.scale_length : 1.0f; float scale_camera = 0.001f / scale; /* we want radius here for the aperture number */ float aperture = 0.5f * scale_camera * focal_len / fstop; @@ -157,7 +155,7 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v effects->dof_params[2] = viewport_size[0] / sensor_scaled; effects->dof_bokeh[0] = rotation; effects->dof_bokeh[1] = ratio; - effects->dof_bokeh[2] = BKE_collection_engine_property_value_get_float(props, "bokeh_max_size"); + effects->dof_bokeh[2] = scene_eval->eevee.bokeh_max_size; /* Precompute values to save instructions in fragment shader. */ effects->dof_bokeh_sides[0] = blades; diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 0b1eb9476fe..646c7a03afd 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -221,7 +221,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object * Normal buffer for deferred passes. */ if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) { - effects->ssr_normal_input = DRW_texture_pool_query_2D(size_fs[0], size_fs[1], GPU_RG16F, + effects->ssr_normal_input = DRW_texture_pool_query_2D(size_fs[0], size_fs[1], GPU_RG16, &draw_engine_eevee_type); GPU_framebuffer_texture_attach(fbl->main_fb, effects->ssr_normal_input, 1, 0); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 21f14371653..8448393aa97 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -423,85 +423,6 @@ static void eevee_engine_free(void) EEVEE_volumes_free(); } -static void eevee_layer_collection_settings_create(RenderEngine *UNUSED(engine), IDProperty *props) -{ - BLI_assert(props && - props->type == IDP_GROUP && - props->subtype == IDP_GROUP_SUB_ENGINE_RENDER); - // BKE_collection_engine_property_add_int(props, "high_quality_sphere_lamps", false); - UNUSED_VARS_NDEBUG(props); -} - -static void eevee_view_layer_settings_create(RenderEngine *UNUSED(engine), IDProperty *props) -{ - BLI_assert(props && - props->type == IDP_GROUP && - props->subtype == IDP_GROUP_SUB_ENGINE_RENDER); - - BKE_collection_engine_property_add_int(props, "gi_diffuse_bounces", 3); - BKE_collection_engine_property_add_int(props, "gi_cubemap_resolution", 512); - BKE_collection_engine_property_add_int(props, "gi_visibility_resolution", 32); - - BKE_collection_engine_property_add_int(props, "taa_samples", 16); - BKE_collection_engine_property_add_int(props, "taa_render_samples", 64); - BKE_collection_engine_property_add_bool(props, "taa_reprojection", true); - - BKE_collection_engine_property_add_bool(props, "sss_enable", false); - BKE_collection_engine_property_add_int(props, "sss_samples", 7); - BKE_collection_engine_property_add_float(props, "sss_jitter_threshold", 0.3f); - BKE_collection_engine_property_add_bool(props, "sss_separate_albedo", false); - - BKE_collection_engine_property_add_bool(props, "ssr_enable", false); - BKE_collection_engine_property_add_bool(props, "ssr_refraction", false); - BKE_collection_engine_property_add_bool(props, "ssr_halfres", true); - BKE_collection_engine_property_add_float(props, "ssr_quality", 0.25f); - BKE_collection_engine_property_add_float(props, "ssr_max_roughness", 0.5f); - BKE_collection_engine_property_add_float(props, "ssr_thickness", 0.2f); - BKE_collection_engine_property_add_float(props, "ssr_border_fade", 0.075f); - BKE_collection_engine_property_add_float(props, "ssr_firefly_fac", 10.0f); - - BKE_collection_engine_property_add_bool(props, "volumetric_enable", false); - BKE_collection_engine_property_add_float(props, "volumetric_start", 0.1f); - BKE_collection_engine_property_add_float(props, "volumetric_end", 100.0f); - BKE_collection_engine_property_add_int(props, "volumetric_tile_size", 8); - BKE_collection_engine_property_add_int(props, "volumetric_samples", 64); - BKE_collection_engine_property_add_float(props, "volumetric_sample_distribution", 0.8f); - BKE_collection_engine_property_add_bool(props, "volumetric_lights", true); - BKE_collection_engine_property_add_float(props, "volumetric_light_clamp", 0.0f); - BKE_collection_engine_property_add_bool(props, "volumetric_shadows", false); - BKE_collection_engine_property_add_int(props, "volumetric_shadow_samples", 16); - BKE_collection_engine_property_add_bool(props, "volumetric_colored_transmittance", true); - - BKE_collection_engine_property_add_bool(props, "gtao_enable", false); - BKE_collection_engine_property_add_bool(props, "gtao_use_bent_normals", true); - BKE_collection_engine_property_add_bool(props, "gtao_bounce", true); - BKE_collection_engine_property_add_float(props, "gtao_distance", 0.2f); - BKE_collection_engine_property_add_float(props, "gtao_factor", 1.0f); - BKE_collection_engine_property_add_float(props, "gtao_quality", 0.25f); - - BKE_collection_engine_property_add_bool(props, "dof_enable", false); - BKE_collection_engine_property_add_float(props, "bokeh_max_size", 100.0f); - BKE_collection_engine_property_add_float(props, "bokeh_threshold", 1.0f); - - float default_bloom_color[3] = {1.0f, 1.0f, 1.0f}; - BKE_collection_engine_property_add_bool(props, "bloom_enable", false); - BKE_collection_engine_property_add_float_array(props, "bloom_color", default_bloom_color, 3); - BKE_collection_engine_property_add_float(props, "bloom_threshold", 0.8f); - BKE_collection_engine_property_add_float(props, "bloom_knee", 0.5f); - BKE_collection_engine_property_add_float(props, "bloom_intensity", 0.8f); - BKE_collection_engine_property_add_float(props, "bloom_radius", 6.5f); - BKE_collection_engine_property_add_float(props, "bloom_clamp", 1.0f); - - BKE_collection_engine_property_add_bool(props, "motion_blur_enable", false); - BKE_collection_engine_property_add_int(props, "motion_blur_samples", 8); - BKE_collection_engine_property_add_float(props, "motion_blur_shutter", 1.0f); - - BKE_collection_engine_property_add_int(props, "shadow_method", SHADOW_ESM); - BKE_collection_engine_property_add_int(props, "shadow_cube_size", 512); - BKE_collection_engine_property_add_int(props, "shadow_cascade_size", 1024); - BKE_collection_engine_property_add_bool(props, "shadow_high_bitdepth", false); -} - static const DrawEngineDataSize eevee_data_size = DRW_VIEWPORT_DATA_SIZE(EEVEE_Data); DrawEngineType draw_engine_eevee_type = { @@ -525,8 +446,6 @@ RenderEngineType DRW_engine_viewport_eevee_type = { EEVEE_ENGINE, N_("Eevee"), RE_INTERNAL | RE_USE_SHADING_NODES | RE_USE_PREVIEW, NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL, &EEVEE_render_update_passes, - &eevee_layer_collection_settings_create, - &eevee_view_layer_settings_create, &draw_engine_eevee_type, {NULL, NULL, NULL} }; diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 3ddb74c838b..c07bf4337db 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -43,6 +43,8 @@ #include "GPU_texture.h" #include "GPU_glew.h" +#include "DEG_depsgraph_query.h" + #include "eevee_engine.h" #include "eevee_private.h" @@ -301,8 +303,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; bool update_all = false; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); /* Shaders */ if (!e_data.probe_filter_glossy_sh) { @@ -324,13 +325,13 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda common_data->ssr_toggle = true; common_data->sss_toggle = true; - int prop_bounce_num = BKE_collection_engine_property_value_get_int(props, "gi_diffuse_bounces"); + int prop_bounce_num = scene_eval->eevee.gi_diffuse_bounces; if (sldata->probes->num_bounce != prop_bounce_num) { sldata->probes->num_bounce = prop_bounce_num; update_all = true; } - int prop_cubemap_res = BKE_collection_engine_property_value_get_int(props, "gi_cubemap_resolution"); + int prop_cubemap_res = scene_eval->eevee.gi_cubemap_resolution; if (sldata->probes->cubemap_res != prop_cubemap_res) { sldata->probes->cubemap_res = prop_cubemap_res; update_all = true; @@ -342,7 +343,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda DRW_TEXTURE_FREE_SAFE(sldata->probe_pool); } - int visibility_res = BKE_collection_engine_property_value_get_int(props, "gi_visibility_resolution"); + const int visibility_res = scene_eval->eevee.gi_visibility_resolution; if (common_data->prb_irradiance_vis_size != visibility_res) { common_data->prb_irradiance_vis_size = visibility_res; update_all = true; diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index 7d2c636e215..d6ee27ce721 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -30,6 +30,8 @@ #include "BKE_object.h" +#include "DEG_depsgraph_query.h" + #include "eevee_engine.h" #include "eevee_private.h" @@ -100,8 +102,7 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata) sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); if (!e_data.shadow_sh) { e_data.shadow_sh = DRW_shader_create( @@ -128,10 +129,10 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata) /* Flip buffers */ SWAP(EEVEE_ShadowCasterBuffer *, sldata->lamps->shcaster_frontbuffer, sldata->lamps->shcaster_backbuffer); - int sh_method = BKE_collection_engine_property_value_get_int(props, "shadow_method"); - int sh_cube_size = BKE_collection_engine_property_value_get_int(props, "shadow_cube_size"); - int sh_cascade_size = BKE_collection_engine_property_value_get_int(props, "shadow_cascade_size"); - int sh_high_bitdepth = BKE_collection_engine_property_value_get_int(props, "shadow_high_bitdepth"); + const int sh_method = scene_eval->eevee.shadow_method; + int sh_cube_size = scene_eval->eevee.shadow_cube_size; + int sh_cascade_size = scene_eval->eevee.shadow_cascade_size; + const bool sh_high_bitdepth = (scene_eval->eevee.flag & SCE_EEVEE_SHADOW_HIGH_BITDEPTH) != 0; EEVEE_LampsInfo *linfo = sldata->lamps; if ((linfo->shadow_cube_size != sh_cube_size) || diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index 0c8f929ec0e..114a2450716 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -108,20 +108,19 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda EEVEE_EffectsInfo *effects = stl->effects; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); Scene *scene = draw_ctx->scene; + View3D *v3d = draw_ctx->v3d; RegionView3D *rv3d = draw_ctx->rv3d; ARegion *ar = draw_ctx->ar; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, - RE_engine_id_BLENDER_EEVEE); - if (BKE_collection_engine_property_value_get_bool(props, "motion_blur_enable")) { + if (scene_eval->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED) { /* Update Motion Blur Matrices */ if (camera) { float persmat[4][4]; - float ctime = BKE_scene_frame_get(scene); - float delta = BKE_collection_engine_property_value_get_float(props, "motion_blur_shutter"); + float ctime = BKE_scene_frame_get(scene_eval); + float delta = scene_eval->eevee.motion_blur_shutter; Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, camera); /* Current matrix */ @@ -155,8 +154,7 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda #endif invert_m4(effects->current_ndc_to_world); - effects->motion_blur_samples = BKE_collection_engine_property_value_get_int(props, - "motion_blur_samples"); + effects->motion_blur_samples = scene_eval->eevee.motion_blur_samples; if (!e_data.motion_blur_sh) { eevee_create_shader_motion_blur(); diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c index 7ad56327251..305daef87d1 100644 --- a/source/blender/draw/engines/eevee/eevee_occlusion.c +++ b/source/blender/draw/engines/eevee/eevee_occlusion.c @@ -31,6 +31,8 @@ #include "DNA_anim_types.h" +#include "DEG_depsgraph_query.h" + #include "BKE_global.h" /* for G.debug_value */ #include "eevee_private.h" @@ -73,11 +75,9 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_EffectsInfo *effects = stl->effects; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, - RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if (BKE_collection_engine_property_value_get_bool(props, "gtao_enable")) { + if (scene_eval->flag & SCE_EEVEE_GTAO_ENABLED) { const float *viewport_size = DRW_viewport_size_get(); const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; @@ -86,19 +86,19 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) eevee_create_shader_occlusion(); } - common_data->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance"); - common_data->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor"); - common_data->ao_quality = 1.0f - BKE_collection_engine_property_value_get_float(props, "gtao_quality"); + common_data->ao_dist = scene_eval->eevee.gtao_distance; + common_data->ao_factor = scene_eval->eevee.gtao_factor; + common_data->ao_quality = 1.0f - scene_eval->eevee.gtao_quality; - common_data->ao_settings = 1.0; /* USE_AO */ - if (BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals")) { - common_data->ao_settings += 2.0; /* USE_BENT_NORMAL */ + common_data->ao_settings = 1.0f; /* USE_AO */ + if (scene_eval->flag & SCE_EEVEE_GTAO_BENT_NORMALS) { + common_data->ao_settings += 2.0f; /* USE_BENT_NORMAL */ } - if (BKE_collection_engine_property_value_get_bool(props, "gtao_denoise")) { - common_data->ao_settings += 4.0; /* USE_DENOISE */ + if (scene_eval->flag & SCE_EEVEE_GTAO_BOUNCE) { + common_data->ao_settings += 4.0f; /* USE_DENOISE */ } - common_data->ao_bounce_fac = (float)BKE_collection_engine_property_value_get_bool(props, "gtao_bounce"); + common_data->ao_bounce_fac = (scene_eval->flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f; effects->gtao_horizons = DRW_texture_pool_query_2D(fs_size[0], fs_size[1], GPU_RGBA8, &draw_engine_eevee_type); @@ -139,10 +139,9 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata EEVEE_EffectsInfo *effects = stl->effects; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if (BKE_collection_engine_property_value_get_bool(props, "gtao_enable")) { + if (scene_eval->flag & SCE_EEVEE_GTAO_ENABLED) { DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index f9d38eaf07b..c95e51548d0 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -125,13 +125,6 @@ enum { VAR_MAT_SSSALBED = (1 << 16), }; -/* Shadow Technique */ -enum { - SHADOW_ESM = 1, - SHADOW_VSM = 2, - SHADOW_METHOD_MAX = 3, -}; - typedef struct EEVEE_BoundSphere { float center[3], radius; } EEVEE_BoundSphere; diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 697379e34d1..2d3cb440c7c 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -400,6 +400,7 @@ static void eevee_render_draw_background(EEVEE_Data *vedata) void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl, const rcti *rect) { const DRWContextState *draw_ctx = DRW_context_state_get(); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); ViewLayer *view_layer = draw_ctx->view_layer; const char *viewname = RE_GetActiveRenderView(engine->re); EEVEE_PassList *psl = vedata->psl; @@ -435,8 +436,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl EEVEE_occlusion_output_init(sldata, vedata); } - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); - uint tot_sample = BKE_collection_engine_property_value_get_int(props, "taa_render_samples"); + uint tot_sample = scene_eval->eevee.taa_render_samples; uint render_samples = 0; if (RE_engine_test_break(engine)) { diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index 56cc905d701..74760b9c828 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -30,6 +30,8 @@ #include "BLI_dynstr.h" #include "BLI_string_utils.h" +#include "DEG_depsgraph_query.h" + #include "eevee_private.h" #include "GPU_texture.h" @@ -68,9 +70,9 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options) datatoc_common_uniforms_lib_glsl, datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl, + datatoc_ambient_occlusion_lib_glsl, datatoc_octahedron_lib_glsl, datatoc_lightprobe_lib_glsl, - datatoc_ambient_occlusion_lib_glsl, datatoc_raytrace_lib_glsl, datatoc_effect_ssr_frag_glsl); @@ -111,16 +113,14 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) const float *viewport_size = DRW_viewport_size_get(); const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, - RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); /* Compute pixel size, (shared with contact shadows) */ copy_v2_v2(common_data->ssr_pixelsize, viewport_size); invert_v2(common_data->ssr_pixelsize); - if (BKE_collection_engine_property_value_get_bool(props, "ssr_enable")) { - const bool use_refraction = BKE_collection_engine_property_value_get_bool(props, "ssr_refraction"); + if (scene_eval->eevee.flag & SCE_EEVEE_SSR_ENABLED) { + const bool use_refraction = (scene_eval->eevee.flag & SCE_EEVEE_SSR_REFRACTION) != 0; if (use_refraction) { /* TODO: Opti: Could be shared. */ @@ -132,12 +132,12 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) }); } - effects->reflection_trace_full = !BKE_collection_engine_property_value_get_bool(props, "ssr_halfres"); - common_data->ssr_thickness = BKE_collection_engine_property_value_get_float(props, "ssr_thickness"); - common_data->ssr_border_fac = BKE_collection_engine_property_value_get_float(props, "ssr_border_fade"); - common_data->ssr_firefly_fac = BKE_collection_engine_property_value_get_float(props, "ssr_firefly_fac"); - common_data->ssr_max_roughness = BKE_collection_engine_property_value_get_float(props, "ssr_max_roughness"); - common_data->ssr_quality = 1.0f - 0.95f * BKE_collection_engine_property_value_get_float(props, "ssr_quality"); + effects->reflection_trace_full = (scene_eval->eevee.flag & SCE_EEVEE_SSR_HALF_RESOLUTION) == 0; + common_data->ssr_thickness = scene_eval->eevee.ssr_thickness; + common_data->ssr_border_fac = scene_eval->eevee.ssr_border_fade; + common_data->ssr_firefly_fac = scene_eval->eevee.ssr_firefly_fac; + common_data->ssr_max_roughness = scene_eval->eevee.ssr_max_roughness; + common_data->ssr_quality = 1.0f - 0.95f * scene_eval->eevee.ssr_quality; common_data->ssr_brdf_bias = 0.1f + common_data->ssr_quality * 0.6f; /* Range [0.1, 0.7]. */ if (common_data->ssr_firefly_fac < 1e-8f) { diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c index d1e760aa123..1a46e0b5c33 100644 --- a/source/blender/draw/engines/eevee/eevee_subsurface.c +++ b/source/blender/draw/engines/eevee/eevee_subsurface.c @@ -29,6 +29,8 @@ #include "BLI_string_utils.h" +#include "DEG_depsgraph_query.h" + #include "eevee_private.h" #include "GPU_texture.h" @@ -69,13 +71,12 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if (BKE_collection_engine_property_value_get_bool(props, "sss_enable")) { - effects->sss_sample_count = 1 + BKE_collection_engine_property_value_get_int(props, "sss_samples") * 2; - effects->sss_separate_albedo = BKE_collection_engine_property_value_get_bool(props, "sss_separate_albedo"); - common_data->sss_jitter_threshold = BKE_collection_engine_property_value_get_float(props, "sss_jitter_threshold"); + if (scene_eval->eevee.flag & SCE_EEVEE_SSS_ENABLED) { + effects->sss_sample_count = 1 + scene_eval->eevee.sss_samples * 2; + effects->sss_separate_albedo = (scene_eval->eevee.flag & SCE_EEVEE_SSS_SEPARATE_ALBEDO) != 0; + common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold; /* Force separate albedo for final render */ if (DRW_state_is_image_render()) { @@ -147,10 +148,9 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat EEVEE_EffectsInfo *effects = stl->effects; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if (BKE_collection_engine_property_value_get_bool(props, "sss_enable")) { + if (scene_eval->flag & SCE_EEVEE_SSS_ENABLED) { DRW_texture_ensure_fullscreen_2D(&txl->sss_dir_accum, GPU_RGBA16F, 0); DRW_texture_ensure_fullscreen_2D(&txl->sss_col_accum, GPU_RGBA16F, 0); diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 889a7f6cdcd..7cd76669fe4 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -32,6 +32,8 @@ #include "BLI_rand.h" #include "BLI_string_utils.h" +#include "DEG_depsgraph_query.h" + #include "eevee_private.h" #include "GPU_texture.h" @@ -192,10 +194,9 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data effects->taa_render_sample = 1; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if ((BKE_collection_engine_property_value_get_int(props, "taa_samples") != 1 && + if (((scene_eval->eevee.taa_samples != 1) && /* FIXME the motion blur camera evaluation is tagging view_updated * thus making the TAA always reset and never stopping rendering. */ (effects->enabled_effects & EFFECT_MOTION_BLUR) == 0) || @@ -204,7 +205,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data float persmat[4][4], viewmat[4][4]; if (!DRW_state_is_image_render() && - BKE_collection_engine_property_value_get_bool(props, "taa_reprojection")) + (scene_eval->eevee.flag & SCE_EEVEE_TAA_REPROJECTION)) { repro_flag = EFFECT_TAA_REPROJECT | EFFECT_VELOCITY_BUFFER | EFFECT_DEPTH_DOUBLE_BUFFER | EFFECT_DOUBLE_BUFFER | EFFECT_POST_BUFFER; effects->taa_reproject_sample = ((effects->taa_reproject_sample + 1) % 16); @@ -221,7 +222,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data view_is_valid = view_is_valid && (ED_screen_animation_no_scrub(wm) == NULL); } - effects->taa_total_sample = BKE_collection_engine_property_value_get_int(props, "taa_samples"); + effects->taa_total_sample = scene_eval->eevee.taa_samples; MAX2(effects->taa_total_sample, 0); DRW_viewport_matrix_get(persmat, DRW_MAT_PERS); diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index 30927d8df6f..2d074eea522 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -41,6 +41,8 @@ #include "ED_screen.h" +#include "DEG_depsgraph_query.h" + #include "eevee_private.h" #include "GPU_draw.h" #include "GPU_texture.h" @@ -155,28 +157,27 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, RE_engine_id_BLENDER_EEVEE); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); const float *viewport_size = DRW_viewport_size_get(); BLI_listbase_clear(&e_data.smoke_domains); - if (BKE_collection_engine_property_value_get_bool(props, "volumetric_enable")) { + if (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_ENABLED) { /* Shaders */ if (!e_data.volumetric_scatter_sh) { eevee_create_shader_volumes(); } - int tile_size = BKE_collection_engine_property_value_get_int(props, "volumetric_tile_size"); + const int tile_size = scene_eval->eevee.volumetric_tile_size; /* Find Froxel Texture resolution. */ int tex_size[3]; tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size)); tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size)); - tex_size[2] = max_ii(BKE_collection_engine_property_value_get_int(props, "volumetric_samples"), 1); + tex_size[2] = max_ii(scene_eval->eevee.volumetric_samples, 1); common_data->vol_coord_scale[0] = viewport_size[0] / (float)(tile_size * tex_size[0]); common_data->vol_coord_scale[1] = viewport_size[1] / (float)(tile_size * tex_size[1]); @@ -286,19 +287,16 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance_history) }); - float integration_start = BKE_collection_engine_property_value_get_float(props, "volumetric_start"); - float integration_end = BKE_collection_engine_property_value_get_float(props, "volumetric_end"); - common_data->vol_light_clamp = BKE_collection_engine_property_value_get_float(props, "volumetric_light_clamp"); - - common_data->vol_shadow_steps = (float)BKE_collection_engine_property_value_get_int(props, "volumetric_shadow_samples"); - if (BKE_collection_engine_property_value_get_bool(props, "volumetric_shadows")) { - } - else { + float integration_start = scene_eval->eevee.volumetric_start; + float integration_end = scene_eval->eevee.volumetric_end; + common_data->vol_light_clamp = scene_eval->eevee.volumetric_light_clamp; + common_data->vol_shadow_steps = (float)scene_eval->eevee.volumetric_shadow_samples; + if ((scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_SHADOWS) == 0) { common_data->vol_shadow_steps = 0; } if (DRW_viewport_is_persp_get()) { - float sample_distribution = BKE_collection_engine_property_value_get_float(props, "volumetric_sample_distribution"); + float sample_distribution = scene_eval->eevee.volumetric_sample_distribution; sample_distribution = 4.0f * (1.00001f - sample_distribution); const float clip_start = common_data->view_vecs[0][2]; @@ -326,7 +324,7 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) common_data->vol_light_clamp = FLT_MAX; } - common_data->vol_use_lights = BKE_collection_engine_property_value_get_bool(props, "volumetric_lights"); + common_data->vol_use_lights = (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_LIGHTS) != 0; return EFFECT_VOLUMETRIC | EFFECT_POST_BUFFER; } diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl index 6c21d7d6fef..0f76f8e1b8c 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -2,12 +2,6 @@ /* Based on Stochastic Screen Space Reflections * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections */ -#ifndef UTIL_TEX -#define UTIL_TEX -uniform sampler2DArray utilTex; -#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) -#endif /* UTIL_TEX */ - #define MAX_MIP 9.0 uniform ivec2 halfresOffset; @@ -183,40 +177,6 @@ const ivec2 neighbors[32] = ivec2[32]( out vec4 fragColor; -void fallback_cubemap( - vec3 N, vec3 V, vec3 W, vec3 viewPosition, float roughness, float roughnessSquared, inout vec4 spec_accum) -{ - /* Specular probes */ - vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared); - - vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); - vec3 bent_normal; -#ifdef SSR_AO - float final_ao = occlusion_compute(N, viewPosition, 1.0, rand, bent_normal); - final_ao = specular_occlusion(dot(N, V), final_ao, roughness); -#else - const float final_ao = 1.0; -#endif - - /* Starts at 1 because 0 is world probe */ - for (int i = 1; i < MAX_PROBE && i < prbNumRenderCube && spec_accum.a < 0.999; ++i) { - CubeData cd = probes_data[i]; - - float fade = probe_attenuation_cube(cd, W); - - if (fade > 0.0) { - vec3 spec = final_ao * probe_evaluate_cube(float(i), cd, W, spec_dir, roughness); - accumulate_light(spec, fade, spec_accum); - } - } - - /* World Specular */ - if (spec_accum.a < 0.999) { - vec3 spec = final_ao * probe_evaluate_world_spec(spec_dir, roughness); - accumulate_light(spec, 1.0, spec_accum); - } -} - #if 0 /* Finish reprojection with motion vectors */ vec3 get_motion_vector(vec3 pos) { diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index 429f6ea92e4..6c1571d5306 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -72,6 +72,12 @@ struct GridData { #define MAX_PLANAR 1 #endif +#ifndef UTIL_TEX +#define UTIL_TEX +uniform sampler2DArray utilTex; +#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) +#endif /* UTIL_TEX */ + layout(std140) uniform probe_block { CubeData probes_data[MAX_PROBE]; }; @@ -196,6 +202,40 @@ vec3 probe_evaluate_planar( return sample; } +void fallback_cubemap( + vec3 N, vec3 V, vec3 W, vec3 viewPosition, float roughness, float roughnessSquared, inout vec4 spec_accum) +{ + /* Specular probes */ + vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared); + + vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); + vec3 bent_normal; +#ifdef SSR_AO + float final_ao = occlusion_compute(N, viewPosition, 1.0, rand, bent_normal); + final_ao = specular_occlusion(dot(N, V), final_ao, roughness); +#else + const float final_ao = 1.0; +#endif + + /* Starts at 1 because 0 is world probe */ + for (int i = 1; i < MAX_PROBE && i < prbNumRenderCube && spec_accum.a < 0.999; ++i) { + CubeData cd = probes_data[i]; + + float fade = probe_attenuation_cube(cd, W); + + if (fade > 0.0) { + vec3 spec = final_ao * probe_evaluate_cube(float(i), cd, W, spec_dir, roughness); + accumulate_light(spec, fade, spec_accum); + } + } + + /* World Specular */ + if (spec_accum.a < 0.999) { + vec3 spec = final_ao * probe_evaluate_world_spec(spec_dir, roughness); + accumulate_light(spec, 1.0, spec_accum); + } +} + #ifdef IRRADIANCE_LIB vec3 probe_evaluate_grid(GridData gd, vec3 W, vec3 N, vec3 localpos) { diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index ec0141953fe..c10d63e1ce7 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -226,7 +226,7 @@ DrawEngineType draw_engine_external_type = { RenderEngineType DRW_engine_viewport_external_type = { NULL, NULL, EXTERNAL_ENGINE, N_("External"), RE_INTERNAL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, &draw_engine_external_type, {NULL, NULL, NULL} }; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl index fc5c085999c..17477e56b40 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl @@ -9,6 +9,7 @@ uniform vec3 objectOverlapColor = vec3(0.0); uniform float shadowMultiplier; uniform float lightMultiplier; uniform float shadowShift = 0.1; +uniform mat3 normalWorldMatrix; uniform vec3 lightDirection; /* light direction in view space */ @@ -57,7 +58,13 @@ void main() #ifdef V3D_LIGHTING_STUDIO - vec3 diffuse_light = get_world_diffuse_light(world_data, normal_viewport); +#ifdef STUDIOLIGHT_ORIENTATION_CAMERA + vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport); +#endif +#ifdef STUDIOLIGHT_ORIENTATION_WORLD + vec3 normal_world = normalWorldMatrix * normal_viewport; + vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world); +#endif vec3 shaded_color = diffuse_light * diffuse_color.rgb; #else /* V3D_LIGHTING_STUDIO */ diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl index b6b13a117c5..6507f1ec707 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl @@ -2,8 +2,19 @@ vec3 get_world_diffuse_light(WorldData world_data, vec3 N) { vec4 result = world_data.diffuse_light_x_pos * clamp(N.x, 0.0, 1.0); result = mix(result, world_data.diffuse_light_x_neg, clamp(-N.x, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_y_pos, clamp( N.y, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_y_neg, clamp(-N.y, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_z_pos, clamp( N.z, 0.0, 1.0)); + result = mix(result, world_data.diffuse_light_y_pos, clamp(-N.y, 0.0, 1.0)); + result = mix(result, world_data.diffuse_light_y_neg, clamp(N.y, 0.0, 1.0)); + result = mix(result, world_data.diffuse_light_z_pos, clamp(N.z, 0.0, 1.0)); return mix(result, world_data.diffuse_light_z_neg, clamp(-N.z, 0.0, 1.0)).xyz; } + +vec3 get_camera_diffuse_light(WorldData world_data, vec3 N) +{ + vec4 result = world_data.diffuse_light_x_pos * clamp(N.x, 0.0, 1.0); + result = mix(result, world_data.diffuse_light_x_neg, clamp(-N.x, 0.0, 1.0)); + result = mix(result, world_data.diffuse_light_z_pos, clamp( N.y, 0.0, 1.0)); + result = mix(result, world_data.diffuse_light_z_neg, clamp(-N.y, 0.0, 1.0)); + result = mix(result, world_data.diffuse_light_y_pos, clamp( N.z, 0.0, 1.0)); + result = mix(result, world_data.diffuse_light_y_neg, clamp(-N.z, 0.0, 1.0)); + return result.xyz; +} diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 248534d7e51..26ae1c289c8 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -38,7 +38,7 @@ RenderEngineType DRW_engine_viewport_workbench_type = { NULL, NULL, WORKBENCH_ENGINE, N_("Workbench"), RE_INTERNAL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, &draw_engine_workbench_solid, {NULL, NULL, NULL} }; diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 743f21eda30..a9c2941eb22 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -64,6 +64,7 @@ static struct { SceneDisplay display; /* world light direction for shadows */ float light_direction_vs[3]; int next_object_id; + float normal_world_matrix[3][3]; } e_data = {{NULL}}; /* Shaders */ @@ -86,7 +87,7 @@ extern DrawEngineType draw_engine_workbench_solid; #define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->shading.light & V3D_LIGHTING_STUDIO || wpd->shading.flag & V3D_SHADING_SHADOW) #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW) #define NORMAL_ENCODING_ENABLED() (true) -//(!SHADOW_ENABLED(wpd)) +#define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD) static char *workbench_build_defines(WORKBENCH_PrivateData *wpd, int drawtype) @@ -99,10 +100,18 @@ static char *workbench_build_defines(WORKBENCH_PrivateData *wpd, int drawtype) BLI_dynstr_appendf(ds, "#define V3D_SHADING_OBJECT_OUTLINE\n"); } if (wpd->shading.flag & V3D_SHADING_SHADOW) { - BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n"); + if (!STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n"); + } } if (wpd->shading.light & V3D_LIGHTING_STUDIO) { BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_STUDIO\n"); + if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_WORLD\n"); + } + else { + BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_CAMERA\n"); + } } if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) { BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n"); @@ -168,10 +177,13 @@ static int get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype) const int DRAWOPTIONS_MASK = V3D_SHADING_OBJECT_OUTLINE | V3D_SHADING_SHADOW; int index = (wpd->shading.flag & DRAWOPTIONS_MASK); index = (index << 2) + wpd->shading.light; + index = (index << 2); /* set the drawtype flag - 0 = OB_SOLID, - 1 = OB_TEXTURE */ - index = index << 1; + 0 = OB_SOLID, + 1 = OB_TEXTURE + 2 = STUDIOLIGHT_ORIENTATION_WORLD + */ + SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD, 2); SET_FLAG_FROM_TEST(index, drawtype == OB_TEXTURE, 1); return index; } @@ -368,6 +380,17 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG } DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); + + if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + float view_matrix_inverse[4][4]; + float rot_matrix[4][4]; + float matrix[4][4]; + axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z); + DRW_viewport_matrix_get(view_matrix_inverse, DRW_MAT_VIEWINV); + mul_m4_m4m4(matrix, rot_matrix, view_matrix_inverse); + copy_m3_m4(e_data.normal_world_matrix, matrix); + DRW_shgroup_uniform_mat3(grp, "normalWorldMatrix", e_data.normal_world_matrix); + } } void workbench_materials_cache_init(WORKBENCH_Data *vedata) @@ -386,17 +409,24 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata) select_deferred_shaders(wpd); /* Deferred Mix Pass */ { - wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), NULL); DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data); - copy_v3_v3(e_data.display.light_direction, scene->display.light_direction); - negate_v3(e_data.display.light_direction); - e_data.display.shadow_shift = scene->display.shadow_shift; + if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED); + float rot_matrix[3][3]; + // float dir[3] = {0.57, 0.57, -0.57}; + axis_angle_to_mat3_single(rot_matrix, 'Z', wpd->shading.studiolight_rot_z); + mul_v3_m3v3(e_data.display.light_direction, rot_matrix, wpd->studio_light->light_direction); + } + else { + copy_v3_v3(e_data.display.light_direction, scene->display.light_direction); + negate_v3(e_data.display.light_direction); + } float view_matrix[4][4]; DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW); mul_v3_mat3_m4v3(e_data.light_direction_vs, view_matrix, e_data.display.light_direction); - + e_data.display.shadow_shift = scene->display.shadow_shift; if (SHADOW_ENABLED(wpd)) { diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 901f009e7ed..574eb245d1b 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -47,6 +47,7 @@ #include "GPU_framebuffer.h" #include "GPU_texture.h" +#include "GPU_shader.h" #include "draw_common.h" #include "draw_cache.h" @@ -229,6 +230,9 @@ struct GPUShader *DRW_shader_create( const char *vert, const char *geom, const char *frag, const char *defines); struct GPUShader *DRW_shader_create_with_lib( const char *vert, const char *geom, const char *frag, const char *lib, const char *defines); +struct GPUShader *DRW_shader_create_with_transform_feedback( + const char *vert, const char *geom, const char *defines, + const GPUShaderTFBType prim_type, const char **varying_names, const int varying_count); struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines); struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines); struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines); @@ -274,6 +278,7 @@ typedef enum { DRW_STATE_ADDITIVE_FULL = (1 << 19), /* Same as DRW_STATE_ADDITIVE but let alpha accumulate without premult. */ DRW_STATE_BLEND_PREMUL = (1 << 20), /* Use that if color is already premult by alpha. */ DRW_STATE_WIRE_SMOOTH = (1 << 21), + DRW_STATE_TRANS_FEEDBACK = (1 << 22), DRW_STATE_WRITE_STENCIL = (1 << 27), DRW_STATE_WRITE_STENCIL_SHADOW = (1 << 28), @@ -310,8 +315,10 @@ DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create(struct GPUMaterial DRWShadingGroup *DRW_shgroup_instance_create( struct GPUShader *shader, DRWPass *pass, struct Gwn_Batch *geom, struct Gwn_VertFormat *format); DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass); +DRWShadingGroup *DRW_shgroup_line_batch_create_with_format(struct GPUShader *shader, DRWPass *pass, struct Gwn_VertFormat *format); DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass); DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size); +DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader, DRWPass *pass, struct Gwn_VertBuf *tf_target); typedef void (DRWCallGenerateFn)( DRWShadingGroup *shgroup, diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index d07febfdd22..d7cc5f0cac6 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -81,7 +81,7 @@ static struct { DRWShadingGroup *bone_box_solid; DRWShadingGroup *bone_box_wire; DRWShadingGroup *bone_box_outline; - DRWShadingGroup *bone_wire_wire; + DRWShadingGroup *bone_wire; DRWShadingGroup *bone_stick; DRWShadingGroup *bone_envelope_solid; DRWShadingGroup *bone_envelope_distance; @@ -171,17 +171,21 @@ static void drw_shgroup_bone_box( } /* Wire */ -static void drw_shgroup_bone_wire_wire(const float (*bone_mat)[4], const float color[4]) +static void drw_shgroup_bone_wire(const float (*bone_mat)[4], const float color[4]) { - if (g_data.bone_wire_wire == NULL) { - struct Gwn_Batch *geom = DRW_cache_bone_wire_wire_outline_get(); - g_data.bone_wire_wire = shgroup_instance_wire(g_data.passes.bone_wire, geom); + if (g_data.bone_wire == NULL) { + g_data.bone_wire = shgroup_dynlines_flat_color(g_data.passes.bone_wire); } - float final_bonemat[4][4]; - mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); - DRW_shgroup_call_dynamic_add(g_data.bone_wire_wire, final_bonemat, color); + float head[3], tail[3]; + mul_v3_m4v3(head, g_data.ob->obmat, bone_mat[3]); + DRW_shgroup_call_dynamic_add(g_data.bone_wire, head, color); + + add_v3_v3v3(tail, bone_mat[3], bone_mat[1]); + mul_m4_v3(g_data.ob->obmat, tail); + DRW_shgroup_call_dynamic_add(g_data.bone_wire, tail, color); } +/* Stick */ static void drw_shgroup_bone_stick( const float (*bone_mat)[4], const float col_wire[4], const float col_bone[4], const float col_head[4], const float col_tail[4]) @@ -327,9 +331,11 @@ static void drw_shgroup_bone_custom_wire(const float (*bone_mat)[4], const float struct Gwn_Batch *geom = DRW_cache_object_wire_outline_get(custom); if (geom) { DRWShadingGroup *shgrp_geom_wire = shgroup_instance_wire(g_data.passes.bone_wire, geom); - float final_bonemat[4][4]; + float final_bonemat[4][4], final_color[4]; mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); - DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, color); + copy_v3_v3(final_color, color); + final_color[3] = 1.0f; /* hack */ + DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, final_color); } } @@ -370,8 +376,11 @@ static void drw_shgroup_bone_relationship_lines(const float start[3], const floa g_data.lines_relationship = shgroup_dynlines_dashed_uniform_color(g_data.passes.relationship_lines, g_theme.wire_color); } /* reverse order to have less stipple overlap */ - DRW_shgroup_call_dynamic_add(g_data.lines_relationship, end); - DRW_shgroup_call_dynamic_add(g_data.lines_relationship, start); + float v[3]; + mul_v3_m4v3(v, g_data.ob->obmat, end); + DRW_shgroup_call_dynamic_add(g_data.lines_relationship, v); + mul_v3_m4v3(v, g_data.ob->obmat, start); + DRW_shgroup_call_dynamic_add(g_data.lines_relationship, v); } static void drw_shgroup_bone_ik_lines(const float start[3], const float end[3]) @@ -381,8 +390,11 @@ static void drw_shgroup_bone_ik_lines(const float start[3], const float end[3]) g_data.lines_ik = shgroup_dynlines_dashed_uniform_color(g_data.passes.relationship_lines, fcolor); } /* reverse order to have less stipple overlap */ - DRW_shgroup_call_dynamic_add(g_data.lines_ik, end); - DRW_shgroup_call_dynamic_add(g_data.lines_ik, start); + float v[3]; + mul_v3_m4v3(v, g_data.ob->obmat, end); + DRW_shgroup_call_dynamic_add(g_data.lines_ik, v); + mul_v3_m4v3(v, g_data.ob->obmat, start); + DRW_shgroup_call_dynamic_add(g_data.lines_ik, v); } static void drw_shgroup_bone_ik_no_target_lines(const float start[3], const float end[3]) @@ -1157,7 +1169,9 @@ static void draw_bone_custom_shape( DRW_select_load_id(select_id | BONESEL_BONE); } - drw_shgroup_bone_custom_solid(disp_mat, col_solid, pchan->custom); + if ((boneflag & BONE_DRAWWIRE) == 0) { + drw_shgroup_bone_custom_solid(disp_mat, col_solid, pchan->custom); + } drw_shgroup_bone_custom_wire(disp_mat, col_wire, pchan->custom); if (select_id != -1) { @@ -1281,12 +1295,12 @@ static void draw_bone_wire( BLI_assert(bbones_mat != NULL); for (int i = pchan->bone->segments; i--; bbones_mat++) { - drw_shgroup_bone_wire_wire(bbones_mat->mat, col_wire); + drw_shgroup_bone_wire(bbones_mat->mat, col_wire); } } else if (eBone) { for (int i = 0; i < eBone->segments; i++) { - drw_shgroup_bone_wire_wire(eBone->disp_bbone_mat[i], col_wire); + drw_shgroup_bone_wire(eBone->disp_bbone_mat[i], col_wire); } } diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 639e4edb32f..96a6a616072 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -116,10 +116,10 @@ void DRW_shape_cache_free(void) /** \name Helper functions * \{ */ -static void add_fancy_edge( +static void UNUSED_FUNCTION(add_fancy_edge)( Gwn_VertBuf *vbo, uint pos_id, uint n1_id, uint n2_id, uint *v_idx, const float co1[3], const float co2[3], -const float n1[3], const float n2[3]) + const float n1[3], const float n2[3]) { GWN_vertbuf_attr_set(vbo, n1_id, *v_idx, n1); GWN_vertbuf_attr_set(vbo, n2_id, *v_idx, n2); @@ -1548,6 +1548,7 @@ static const float bone_octahedral_smooth_normals[6][3] = { { 0.0f, 1.0f, 0.0f} }; +#if 0 /* UNUSED */ static const uint bone_octahedral_wire[24] = { 0, 1, 1, 5, 5, 3, 3, 0, 0, 4, 4, 5, 5, 2, 2, 0, @@ -1561,6 +1562,7 @@ static const uint bone_octahedral_wire_adjacent_face[24] = { 2, 3, 6, 7, 4, 5, 0, 1, 0, 4, 1, 5, 2, 6, 3, 7, }; +#endif static const uint bone_octahedral_solid_tris[8][3] = { {2, 1, 0}, /* bottom */ @@ -1650,37 +1652,6 @@ Gwn_Batch *DRW_cache_bone_octahedral_get(void) return SHC.drw_bone_octahedral; } -Gwn_Batch *DRW_cache_bone_octahedral_wire_outline_get(void) -{ - if (!SHC.drw_bone_octahedral_wire) { - uint v_idx = 0; - - static Gwn_VertFormat format = { 0 }; - static struct { uint pos, n1, n2; } attr_id; - if (format.attrib_ct == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.n1 = GWN_vertformat_attr_add(&format, "N1", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.n2 = GWN_vertformat_attr_add(&format, "N2", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - } - - /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 12 * 2); - - for (int i = 0; i < 12; i++) { - const float *co1 = bone_octahedral_verts[bone_octahedral_wire[i * 2]]; - const float *co2 = bone_octahedral_verts[bone_octahedral_wire[i * 2 + 1]]; - const float *n1 = bone_octahedral_solid_normals[bone_octahedral_wire_adjacent_face[i * 2]]; - const float *n2 = bone_octahedral_solid_normals[bone_octahedral_wire_adjacent_face[i * 2 + 1]]; - add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n1, n2); - } - - SHC.drw_bone_octahedral_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); - } - return SHC.drw_bone_octahedral_wire; -} - - /* XXX TODO move that 1 unit cube to more common/generic place? */ static const float bone_box_verts[8][3] = { { 1.0f, 0.0f, 1.0f}, @@ -1704,6 +1675,7 @@ static const float bone_box_smooth_normals[8][3] = { {-M_SQRT3, M_SQRT3, M_SQRT3}, }; +#if 0 /* UNUSED */ static const uint bone_box_wire[24] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, @@ -1717,6 +1689,7 @@ static const uint bone_box_wire_adjacent_face[24] = { 3, 10, 5, 10, 7, 11, 9, 11, 3, 8, 2, 5, 4, 7, 6, 9, }; +#endif static const uint bone_box_solid_tris[12][3] = { {0, 2, 1}, /* bottom */ @@ -1820,64 +1793,6 @@ Gwn_Batch *DRW_cache_bone_box_get(void) return SHC.drw_bone_box; } -Gwn_Batch *DRW_cache_bone_box_wire_outline_get(void) -{ - if (!SHC.drw_bone_box_wire) { - uint v_idx = 0; - - static Gwn_VertFormat format = { 0 }; - static struct { uint pos, n1, n2; } attr_id; - if (format.attrib_ct == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.n1 = GWN_vertformat_attr_add(&format, "N1", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.n2 = GWN_vertformat_attr_add(&format, "N2", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - } - - /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 12 * 2); - - for (int i = 0; i < 12; i++) { - const float *co1 = bone_box_verts[bone_box_wire[i * 2]]; - const float *co2 = bone_box_verts[bone_box_wire[i * 2 + 1]]; - const float *n1 = bone_box_solid_normals[bone_box_wire_adjacent_face[i * 2]]; - const float *n2 = bone_box_solid_normals[bone_box_wire_adjacent_face[i * 2 + 1]]; - add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n1, n2); - } - - SHC.drw_bone_box_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); - } - return SHC.drw_bone_box_wire; -} - - -Gwn_Batch *DRW_cache_bone_wire_wire_outline_get(void) -{ - if (!SHC.drw_bone_wire_wire) { - uint v_idx = 0; - - static Gwn_VertFormat format = { 0 }; - static struct { uint pos, n1, n2; } attr_id; - if (format.attrib_ct == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.n1 = GWN_vertformat_attr_add(&format, "N1", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.n2 = GWN_vertformat_attr_add(&format, "N2", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - } - - /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 2); - - const float co1[3] = {0.0f, 0.0f, 0.0f}; - const float co2[3] = {0.0f, 1.0f, 0.0f}; - const float n[3] = {1.0f, 0.0f, 0.0f}; - add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n, n); - - SHC.drw_bone_wire_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); - } - return SHC.drw_bone_wire_wire; -} - /* Helpers for envelope bone's solid sphere-with-hidden-equatorial-cylinder. * Note that here we only encode head/tail in forth component of the vector. */ static void benv_lat_lon_to_co(const float lat, const float lon, float r_nor[3]) diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 6848285706a..b9a569b3ace 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -97,10 +97,7 @@ struct Gwn_Batch *DRW_cache_lightprobe_planar_get(void); /* Bones */ struct Gwn_Batch *DRW_cache_bone_octahedral_get(void); -struct Gwn_Batch *DRW_cache_bone_octahedral_wire_outline_get(void); struct Gwn_Batch *DRW_cache_bone_box_get(void); -struct Gwn_Batch *DRW_cache_bone_box_wire_outline_get(void); -struct Gwn_Batch *DRW_cache_bone_wire_wire_outline_get(void); struct Gwn_Batch *DRW_cache_bone_envelope_solid_get(void); struct Gwn_Batch *DRW_cache_bone_envelope_outline_get(void); struct Gwn_Batch *DRW_cache_bone_envelope_head_wire_outline_get(void); diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index a1eb98a85e2..c6cc243638b 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -38,10 +38,12 @@ #include "BLI_string.h" #include "BLI_ghash.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_particle_types.h" -#include "BKE_DerivedMesh.h" +#include "BKE_mesh.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -253,12 +255,12 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys, ParticleData *particle = &psys->particles[parent_index]; int num = particle->num_dmcache; if (num == DMCACHE_NOTFOUND) { - if (particle->num < psmd->dm_final->getNumTessFaces(psmd->dm_final)) { + if (particle->num < psmd->mesh_final->totface) { num = particle->num; } } if (num != DMCACHE_NOTFOUND) { - MFace *mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE); + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, @@ -286,8 +288,7 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys, ChildParticle *particle = &psys->child[child_index]; int num = particle->num; if (num != DMCACHE_NOTFOUND) { - MFace *mface = psmd->dm_final->getTessFaceData( - psmd->dm_final, num, CD_MFACE); + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs( mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); @@ -456,8 +457,8 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, float (**parent_uvs)[2] = NULL; if (psmd != NULL) { - if (CustomData_has_layer(&psmd->dm_final->loopData, CD_MLOOPUV)) { - num_uv_layers = CustomData_number_of_layers(&psmd->dm_final->loopData, CD_MLOOPUV); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { + num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); } } @@ -472,7 +473,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, uv_id = MEM_mallocN(sizeof(*uv_id) * num_uv_layers, "UV attrib format"); for (int i = 0; i < num_uv_layers; i++) { - const char *name = CustomData_get_layer_name(&psmd->dm_final->loopData, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name)); @@ -490,10 +491,10 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, true); if (num_uv_layers) { - DM_ensure_tessface(psmd->dm_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); mtfaces = MEM_mallocN(sizeof(*mtfaces) * num_uv_layers, "Faces UV layers"); for (int i = 0; i < num_uv_layers; i++) { - mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->dm_final->faceData, CD_MTFACE, i); + mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MTFACE, i); } } @@ -584,7 +585,7 @@ static void particle_batch_cache_ensure_pos(Object *object, for (curr_point = 0, i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { state.time = DEG_get_ctime(draw_ctx->depsgraph); - if (!psys_get_particle_state(&sim, curr_point, &state, 0)) { + if (!psys_get_particle_state(&sim, i, &state, 0)) { continue; } diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index ba5e04df512..b51b15b20ed 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -203,6 +203,7 @@ static struct { struct Gwn_VertFormat *instance_bone_envelope_distance; struct Gwn_VertFormat *instance_bone_envelope_outline; struct Gwn_VertFormat *instance_mball_handles; + struct Gwn_VertFormat *dynlines_color; } g_formats = {NULL}; void DRW_globals_free(void) @@ -218,6 +219,20 @@ void DRW_globals_free(void) } } +DRWShadingGroup *shgroup_dynlines_flat_color(DRWPass *pass) +{ + GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR); + + DRW_shgroup_instance_format(g_formats.dynlines_color, { + {"pos" , DRW_ATTRIB_FLOAT, 3}, + {"color" , DRW_ATTRIB_FLOAT, 4} + }); + + DRWShadingGroup *grp = DRW_shgroup_line_batch_create_with_format(sh, pass, g_formats.dynlines_color); + + return grp; +} + DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(DRWPass *pass, float color[4]) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 9c36ecd995c..11cff02d6c9 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -99,6 +99,7 @@ typedef struct GlobalsUboStorage { void DRW_globals_update(void); void DRW_globals_free(void); +struct DRWShadingGroup *shgroup_dynlines_flat_color(struct DRWPass *pass); struct DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(struct DRWPass *pass, float color[4]); struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, float color[4], float *size); struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, float color[4]); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 8c7435bdd1f..3e7790b421f 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1605,12 +1605,12 @@ void DRW_draw_select_loop( obedit_mode = CTX_MODE_EDIT_ARMATURE; } } - bool use_bone_selection_overlay = false; if (v3d->overlay.flag &= V3D_OVERLAY_BONE_SELECTION) { if (!(v3d->flag2 &= V3D_RENDER_OVERRIDE)) { Object *obpose = OBPOSE_FROM_OBACT(obact); if (obpose) { - use_bone_selection_overlay = true; + use_obedit = true; + obedit_mode = CTX_MODE_POSE; } } } @@ -1628,17 +1628,8 @@ void DRW_draw_select_loop( drw_engines_enable_from_mode(obedit_mode); } else { - /* when in pose mode and overlays enable and bone selection overlay - active, switch order as the bone selection must have more precedence - than the rest of the scene */ - if (use_bone_selection_overlay) { - drw_engines_enable_from_object_mode(); - drw_engines_enable_basic(); - } - else { - drw_engines_enable_basic(); - drw_engines_enable_from_object_mode(); - } + drw_engines_enable_basic(); + drw_engines_enable_from_object_mode(); } /* Setup viewport */ @@ -2026,10 +2017,10 @@ void DRW_engine_register(DrawEngineType *draw_engine_type) void DRW_engines_register(void) { #ifdef WITH_CLAY_ENGINE - RE_engines_register(NULL, &DRW_engine_viewport_clay_type); + RE_engines_register(&DRW_engine_viewport_clay_type); #endif - RE_engines_register(NULL, &DRW_engine_viewport_eevee_type); - RE_engines_register(NULL, &DRW_engine_viewport_workbench_type); + RE_engines_register(&DRW_engine_viewport_eevee_type); + RE_engines_register(&DRW_engine_viewport_workbench_type); DRW_engine_register(&draw_engine_workbench_solid); diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index e71da41f118..0f9a68552fe 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -193,6 +193,7 @@ typedef enum { DRW_SHG_TRIANGLE_BATCH, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL, + DRW_SHG_FEEDBACK_TRANSFORM, } DRWShadingGroupType; struct DRWShadingGroup { @@ -206,6 +207,10 @@ struct DRWShadingGroup { struct { /* DRW_SHG_NORMAL */ DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */ } calls; + struct { /* DRW_SHG_FEEDBACK_TRANSFORM */ + DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */ + struct Gwn_VertBuf *tfeedback_target; /* Transform Feedback target. */ + }; struct { /* DRW_SHG_***_BATCH */ struct Gwn_Batch *batch_geom; /* Result of call batching */ struct Gwn_VertBuf *batch_vbo; diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 306ca0c6a3c..1e2036714bf 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -353,7 +353,7 @@ static DRWCallState *drw_call_state_object(DRWShadingGroup *shgroup, float (*obm void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4]) { BLI_assert(geom != NULL); - BLI_assert(shgroup->type == DRW_SHG_NORMAL); + BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls); call->state = drw_call_state_create(shgroup, obmat, NULL); @@ -797,18 +797,23 @@ DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPas return shgroup; } -DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass) +DRWShadingGroup *DRW_shgroup_line_batch_create_with_format(struct GPUShader *shader, DRWPass *pass, Gwn_VertFormat *format) { - DRW_shgroup_instance_format(g_pos_format, {{"pos", DRW_ATTRIB_FLOAT, 3}}); - DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); shgroup->type = DRW_SHG_LINE_BATCH; - drw_shgroup_batching_init(shgroup, shader, g_pos_format); + drw_shgroup_batching_init(shgroup, shader, format); return shgroup; } +DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass) +{ + DRW_shgroup_instance_format(g_pos_format, {{"pos", DRW_ATTRIB_FLOAT, 3}}); + + return DRW_shgroup_line_batch_create_with_format(shader, pass, g_pos_format); +} + /* Very special batch. Use this if you position * your vertices with the vertex shader * and dont need any VBO attrib */ @@ -828,6 +833,18 @@ DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DR return shgroup; } +DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader, DRWPass *pass, Gwn_VertBuf *tf_target) +{ + DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); + shgroup->type = DRW_SHG_FEEDBACK_TRANSFORM; + + drw_shgroup_init(shgroup, shader); + + shgroup->tfeedback_target = tf_target; + + return shgroup; +} + /* Specify an external batch instead of adding each attrib one by one. */ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batch) { diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 033168680b8..78ac96e41b2 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -102,6 +102,21 @@ void drw_state_set(DRWState state) } } + /* Raster Discard */ + { + if (CHANGED_ANY(DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | + DRW_STATE_WRITE_STENCIL | DRW_STATE_WRITE_STENCIL_SHADOW)) + { + if ((state & (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | + DRW_STATE_WRITE_STENCIL | DRW_STATE_WRITE_STENCIL_SHADOW)) != 0) { + glDisable(GL_RASTERIZER_DISCARD); + } + else { + glEnable(GL_RASTERIZER_DISCARD); + } + } + } + /* Cull */ { DRWState test; @@ -900,6 +915,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) int val; float fval; const bool shader_changed = (DST.shader != shgroup->shader); + bool use_tfeedback = false; if (shader_changed) { if (DST.shader) GPU_shader_unbind(); @@ -907,6 +923,13 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) DST.shader = shgroup->shader; } + if ((pass_state & DRW_STATE_TRANS_FEEDBACK) != 0 && + (shgroup->type == DRW_SHG_FEEDBACK_TRANSFORM)) + { + use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader, + shgroup->tfeedback_target->vbo_id); + } + release_ubo_slots(shader_changed); release_texture_slots(shader_changed); @@ -1023,7 +1046,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) #endif /* Rendering Calls */ - if (!ELEM(shgroup->type, DRW_SHG_NORMAL)) { + if (!ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)) { /* Replacing multiple calls with only one */ if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) { if (shgroup->type == DRW_SHG_INSTANCE_EXTERNAL) { @@ -1104,6 +1127,10 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) glFrontFace(DST.frontface); } + if (use_tfeedback) { + GPU_shader_transform_feedback_disable(shgroup->shader); + } + /* TODO: remove, (currently causes alpha issue with sculpt, need to investigate) */ DRW_state_reset(); } diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 06a579c2208..77fcb766743 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -295,6 +295,14 @@ GPUShader *DRW_shader_create_with_lib( return sh; } +GPUShader *DRW_shader_create_with_transform_feedback( + const char *vert, const char *geom, const char *defines, + const GPUShaderTFBType prim_type, const char **varying_names, const int varying_count) +{ + return GPU_shader_create_ex(vert, NULL, geom, NULL, defines, GPU_SHADER_FLAGS_NONE, + prim_type, varying_names, varying_count); +} + GPUShader *DRW_shader_create_2D(const char *frag, const char *defines) { return GPU_shader_create(datatoc_gpu_shader_2D_vert_glsl, frag, NULL, NULL, defines); diff --git a/source/blender/draw/modes/edit_armature_mode.c b/source/blender/draw/modes/edit_armature_mode.c index 0288a027b7c..7992bc73f2d 100644 --- a/source/blender/draw/modes/edit_armature_mode.c +++ b/source/blender/draw/modes/edit_armature_mode.c @@ -165,14 +165,6 @@ static void EDIT_ARMATURE_draw_scene(void *vedata) DRW_draw_pass(psl->bone_axes); } -#if 0 -void EDIT_ARMATURE_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - //BKE_collection_engine_property_add_int(ces, "show_occlude_wire", false); -} -#endif - static const DrawEngineDataSize EDIT_ARMATURE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_ARMATURE_Data); DrawEngineType draw_engine_edit_armature_type = { diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index 2a383530523..bf3120882ea 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -319,27 +319,6 @@ static void EDIT_CURVE_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh); } -/* Create collection settings here. - * - * Be sure to add this function there : - * source/blender/draw/DRW_engine.h - * source/blender/blenkernel/intern/layer.c - * source/blenderplayer/bad_level_call_stubs/stubs.c - * - * And relevant collection settings to : - * source/blender/makesrna/intern/rna_scene.c - * source/blender/blenkernel/intern/layer.c - */ -#if 0 -void EDIT_CURVE_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false); - // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0); - // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f); -} -#endif - static const DrawEngineDataSize EDIT_CURVE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_CURVE_Data); DrawEngineType draw_engine_edit_curve_type = { diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c index 13c0d6660c7..bcd3fa39be4 100644 --- a/source/blender/draw/modes/edit_lattice_mode.c +++ b/source/blender/draw/modes/edit_lattice_mode.c @@ -259,27 +259,6 @@ static void EDIT_LATTICE_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh); } -/* Create collection settings here. - * - * Be sure to add this function there : - * source/blender/draw/DRW_engine.h - * source/blender/blenkernel/intern/layer.c - * source/blenderplayer/bad_level_call_stubs/stubs.c - * - * And relevant collection settings to : - * source/blender/makesrna/intern/rna_scene.c - * source/blender/blenkernel/intern/layer.c - */ -#if 0 -void EDIT_LATTICE_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false); - // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0); - // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f); -} -#endif - static const DrawEngineDataSize EDIT_LATTICE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_LATTICE_Data); DrawEngineType draw_engine_edit_lattice_type = { diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c index e7b07c36882..aa848764fe3 100644 --- a/source/blender/draw/modes/edit_metaball_mode.c +++ b/source/blender/draw/modes/edit_metaball_mode.c @@ -215,27 +215,6 @@ static void EDIT_METABALL_engine_free(void) // DRW_SHADER_FREE_SAFE(custom_shader); } -/* Create collection settings here. - * - * Be sure to add this function there : - * source/blender/draw/DRW_engine.h - * source/blender/blenkernel/intern/layer.c - * source/blenderplayer/bad_level_call_stubs/stubs.c - * - * And relevant collection settings to : - * source/blender/makesrna/intern/rna_scene.c - * source/blender/blenkernel/intern/layer.c - */ -#if 0 -void EDIT_METABALL_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false); - // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0); - // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f); -} -#endif - static const DrawEngineDataSize EDIT_METABALL_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_METABALL_Data); DrawEngineType draw_engine_edit_metaball_type = { diff --git a/source/blender/draw/modes/edit_surface_mode.c b/source/blender/draw/modes/edit_surface_mode.c index 2856ec81053..5059dca2bff 100644 --- a/source/blender/draw/modes/edit_surface_mode.c +++ b/source/blender/draw/modes/edit_surface_mode.c @@ -231,27 +231,6 @@ static void EDIT_SURFACE_engine_free(void) // DRW_SHADER_FREE_SAFE(custom_shader); } -/* Create collection settings here. - * - * Be sure to add this function there : - * source/blender/draw/DRW_engine.h - * source/blender/blenkernel/intern/layer.c - * source/blenderplayer/bad_level_call_stubs/stubs.c - * - * And relevant collection settings to : - * source/blender/makesrna/intern/rna_scene.c - * source/blender/blenkernel/intern/layer.c - */ -#if 0 -void EDIT_SURFACE_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false); - // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0); - // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f); -} -#endif - static const DrawEngineDataSize EDIT_SURFACE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_SURFACE_Data); DrawEngineType draw_engine_edit_surface_type = { diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c index bbe253b7982..8070c314c54 100644 --- a/source/blender/draw/modes/edit_text_mode.c +++ b/source/blender/draw/modes/edit_text_mode.c @@ -272,27 +272,6 @@ static void EDIT_TEXT_engine_free(void) // DRW_SHADER_FREE_SAFE(custom_shader); } -/* Create collection settings here. - * - * Be sure to add this function there : - * source/blender/draw/DRW_engine.h - * source/blender/blenkernel/intern/layer.c - * source/blenderplayer/bad_level_call_stubs/stubs.c - * - * And relevant collection settings to : - * source/blender/makesrna/intern/rna_scene.c - * source/blender/blenkernel/intern/layer.c - */ -#if 0 -void EDIT_TEXT_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false); - // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0); - // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f); -} -#endif - static const DrawEngineDataSize EDIT_TEXT_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_TEXT_Data); DrawEngineType draw_engine_edit_text_type = { diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 9f25818b272..9c83a87018f 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -379,27 +379,6 @@ static void PAINT_TEXTURE_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader); } -/* Create collection settings here. - * - * Be sure to add this function there : - * source/blender/draw/DRW_engine.h - * source/blender/blenkernel/intern/layer.c - * source/blenderplayer/bad_level_call_stubs/stubs.c - * - * And relevant collection settings to : - * source/blender/makesrna/intern/rna_scene.c - * source/blender/blenkernel/intern/layer.c - */ -#if 0 -void PAINT_TEXTURE_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false); - // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0); - // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f); -} -#endif - static const DrawEngineDataSize PAINT_TEXTURE_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_TEXTURE_Data); DrawEngineType draw_engine_paint_texture_type = { diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 513d9aebb4d..f138704cced 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -202,7 +202,7 @@ static void POSE_cache_populate(void *vedata, Object *ob) DRW_shgroup_armature_pose(ob, passes); } } - else if (ob->type == OB_MESH && POSE_is_bone_selection_overlay_active() && POSE_is_driven_by_active_armature(ob)) { + else if (ob->type == OB_MESH && !DRW_state_is_select() && POSE_is_bone_selection_overlay_active() && POSE_is_driven_by_active_armature(ob)) { struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); if (geom) { DRW_shgroup_call_object_add(stl->g_data->bone_selection_shgrp, geom, ob); @@ -244,6 +244,12 @@ static void POSE_draw_scene(void *vedata) const bool transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0; const bool bone_selection_overlay = POSE_is_bone_selection_overlay_active(); + if (DRW_state_is_select()) { + DRW_draw_pass(psl->bone_solid); + DRW_draw_pass(psl->bone_wire); + return; + } + if(bone_selection_overlay) { GPU_framebuffer_bind(dfbl->default_fb); DRW_draw_pass(psl->bone_selection); @@ -276,25 +282,6 @@ static void POSE_draw_scene(void *vedata) DRW_draw_pass(psl->bone_axes); } -/* Create collection settings here. - * - * Be sure to add this function there : - * source/blender/draw/DRW_engine.h - * source/blender/blenkernel/intern/layer.c - * source/blenderplayer/bad_level_call_stubs/stubs.c - * - * And relevant collection settings to : - * source/blender/makesrna/intern/rna_scene.c - * source/blender/blenkernel/intern/layer.c - */ -#if 0 -void POSE_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - // BKE_collection_engine_property_add_int(ces, "foo", 37); -} -#endif - static const DrawEngineDataSize POSE_data_size = DRW_VIEWPORT_DATA_SIZE(POSE_Data); DrawEngineType draw_engine_pose_type = { diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c index 70e40a83539..56b5898a6cf 100644 --- a/source/blender/draw/modes/sculpt_mode.c +++ b/source/blender/draw/modes/sculpt_mode.c @@ -263,27 +263,6 @@ static void SCULPT_engine_free(void) // DRW_SHADER_FREE_SAFE(custom_shader); } -/* Create collection settings here. - * - * Be sure to add this function there : - * source/blender/draw/DRW_engine.h - * source/blender/blenkernel/intern/layer.c - * source/blenderplayer/bad_level_call_stubs/stubs.c - * - * And relevant collection settings to : - * source/blender/makesrna/intern/rna_scene.c - * source/blender/blenkernel/intern/layer.c - */ -#if 0 -void SCULPT_collection_settings_create(CollectionEngineSettings *ces) -{ - BLI_assert(ces); - // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false); - // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0); - // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f); -} -#endif - static const DrawEngineDataSize SCULPT_data_size = DRW_VIEWPORT_DATA_SIZE(SCULPT_Data); DrawEngineType draw_engine_sculpt_type = { diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 787cf7f0524..dfa5a51a775 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -226,9 +226,14 @@ typedef struct MirrTopoStore_t { bool ED_mesh_mirrtopo_recalc_check( struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store); +bool ED_mesh_mirrtopo_recalc_check__real_mesh( + struct Mesh *me, struct Mesh *dm, MirrTopoStore_t *mesh_topo_store); void ED_mesh_mirrtopo_init( struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store, const bool skip_em_vert_array_init); +void ED_mesh_mirrtopo_init__real_mesh( + struct Mesh *me, struct Mesh *dm, MirrTopoStore_t *mesh_topo_store, + const bool skip_em_vert_array_init); void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store); @@ -318,16 +323,21 @@ int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op); /* mirror lookup api */ int ED_mesh_mirror_spatial_table( struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, const float co[3], char mode); +int ED_mesh_mirror_spatial_table__real_mesh( + struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh, const float co[3], char mode); int ED_mesh_mirror_topo_table(struct Object *ob, struct DerivedMesh *dm, char mode); +int ED_mesh_mirror_topo_table__real_mesh(struct Object *ob, struct Mesh *mesh, char mode); /* retrieves mirrored cache vert, or NULL if there isn't one. * note: calling this without ensuring the mirror cache state * is bad.*/ int mesh_get_x_mirror_vert(struct Object *ob, struct DerivedMesh *dm, int index, const bool use_topology); +int mesh_get_x_mirror_vert__real_mesh(struct Object *ob, struct Mesh *mesh, int index, const bool use_topology); struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em, struct BMVert *eve, const float co[3], int index, const bool use_topology); int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm); +int *mesh_get_x_mirror_faces__real_mesh(struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh); int ED_mesh_mirror_get_vert(struct Object *ob, int index); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 4b22e691885..3d17afc2878 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -173,7 +173,7 @@ void ED_screen_update_after_scene_change( const struct bScreen *screen, struct Scene *scene_new, struct ViewLayer *view_layer); -void ED_screen_set_active_region(struct bContext *C, const int xy[2]); +void ED_screen_set_active_region(struct bContext *C, struct wmWindow *win, const int xy[2]); void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen); void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable); void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh); diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index 465a91ad0d0..d65679e1872 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -119,7 +119,6 @@ bool ED_transform_snap_object_project_view3d_ex( const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, - float *ray_depth, float r_loc[3], float r_no[3], int *r_index, struct Object **r_ob, float r_obmat[4][4]); bool ED_transform_snap_object_project_view3d( @@ -127,7 +126,6 @@ bool ED_transform_snap_object_project_view3d( const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, - float *ray_depth, /* return args */ float r_loc[3], float r_no[3]); bool ED_transform_snap_object_project_view3d_mixed( diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index ca5af7a535d..e75b133b5bd 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -37,6 +37,7 @@ #include "BKE_global.h" #include "BKE_editmesh.h" #include "BKE_unit.h" +#include "BKE_layer.h" #include "RNA_define.h" #include "RNA_access.h" @@ -77,15 +78,22 @@ static const float value_scale_per_inch[NUM_VALUE_KINDS] = { 0.0f, 100.0f, 1.0f, typedef struct { BMEditMesh *em; + BMBackup mesh_backup; +} BevelObjectStore; + + +typedef struct { float initial_length[NUM_VALUE_KINDS]; float scale[NUM_VALUE_KINDS]; NumInput num_input[NUM_VALUE_KINDS]; float shift_value[NUM_VALUE_KINDS]; /* The current value when shift is pressed. Negative when shift not active. */ bool is_modal; + BevelObjectStore *ob_store; + uint ob_store_len; + /* modal only */ float mcenter[2]; - BMBackup mesh_backup; void *draw_handle_pixel; short twflag; short value_mode; /* Which value does mouse movement and numeric input affect? */ @@ -128,24 +136,35 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op) static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) { - Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); BevelData *opdata; + ViewLayer *view_layer = CTX_data_view_layer(C); float pixels_per_inch; int i; - if (em->bm->totvertsel == 0) { - return false; - } - if (is_modal) { RNA_float_set(op->ptr, "offset", 0.0f); } op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator"); + uint objects_used_len = 0; + + { + uint ob_store_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &ob_store_len); + opdata->ob_store = MEM_malloc_arrayN(ob_store_len, sizeof(*opdata->ob_store), __func__); + for (uint ob_index = 0; ob_index < ob_store_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + if (em->bm->totvertsel > 0) { + opdata->ob_store[objects_used_len].em = em; + objects_used_len++; + } + } + MEM_freeN(objects); + opdata->ob_store_len = objects_used_len; + } - opdata->em = em; opdata->is_modal = is_modal; opdata->value_mode = OFFSET_VALUE; opdata->segments = (float) RNA_int_get(op->ptr, "segments"); @@ -174,7 +193,9 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); - opdata->mesh_backup = EDBM_redo_state_store(em); + for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { + opdata->ob_store[ob_index].mesh_backup = EDBM_redo_state_store(opdata->ob_store[ob_index].em); + } opdata->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL); G.moving = G_TRANSFORM_EDIT; @@ -191,8 +212,10 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) static bool edbm_bevel_calc(wmOperator *op) { BevelData *opdata = op->customdata; - BMEditMesh *em = opdata->em; + BMEditMesh *em; BMOperator bmop; + bool changed = false; + const float offset = RNA_float_get(op->ptr, "offset"); const int offset_type = RNA_enum_get(op->ptr, "offset_type"); const int segments = RNA_int_get(op->ptr, "segments"); @@ -202,40 +225,45 @@ static bool edbm_bevel_calc(wmOperator *op) int material = RNA_int_get(op->ptr, "material"); const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide"); - /* revert to original mesh */ - if (opdata->is_modal) { - EDBM_redo_state_restore(opdata->mesh_backup, em, false); - } - if (em->ob) { - material = CLAMPIS(material, -1, em->ob->totcol - 1); - } + for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { + em = opdata->ob_store[ob_index].em; - EDBM_op_init(em, &bmop, op, - "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b " - "material=%i loop_slide=%b", - BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, - clamp_overlap, material, loop_slide); + /* revert to original mesh */ + if (opdata->is_modal) { + EDBM_redo_state_restore(opdata->ob_store[ob_index].mesh_backup, em, false); + } - BMO_op_exec(em->bm, &bmop); + if (em->ob) { + material = CLAMPIS(material, -1, em->ob->totcol - 1); + } - if (offset != 0.0f) { - /* not essential, but we may have some loose geometry that - * won't get bevel'd and better not leave it selected */ - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); - } + EDBM_op_init(em, &bmop, op, + "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b " + "material=%i loop_slide=%b", + BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, + clamp_overlap, material, loop_slide); - /* no need to de-select existing geometry */ - if (!EDBM_op_finish(em, &bmop, op, true)) { - return false; - } + BMO_op_exec(em->bm, &bmop); - EDBM_mesh_normals_update(opdata->em); + if (offset != 0.0f) { + /* not essential, but we may have some loose geometry that + * won't get bevel'd and better not leave it selected */ + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); + } + + /* no need to de-select existing geometry */ + if (!EDBM_op_finish(em, &bmop, op, true)) { + continue; + } - EDBM_update_generic(opdata->em, true, true); + EDBM_mesh_normals_update(em); - return true; + EDBM_update_generic(em, true, true); + changed = true; + } + return changed; } static void edbm_bevel_exit(bContext *C, wmOperator *op) @@ -251,14 +279,17 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op) if (opdata->is_modal) { View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); - EDBM_redo_state_free(&opdata->mesh_backup, NULL, false); + for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { + EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, NULL, false); + } ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel); if (v3d) { v3d->twflag = opdata->twflag; } G.moving = 0; } - MEM_freeN(opdata); + MEM_SAFE_FREE(opdata->ob_store); + MEM_SAFE_FREE(op->customdata); op->customdata = NULL; } @@ -266,8 +297,10 @@ static void edbm_bevel_cancel(bContext *C, wmOperator *op) { BevelData *opdata = op->customdata; if (opdata->is_modal) { - EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, true); - EDBM_update_generic(opdata->em, false, true); + for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { + EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, opdata->ob_store[ob_index].em, true); + EDBM_update_generic(opdata->ob_store[ob_index].em, false, true); + } } edbm_bevel_exit(C, op); diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c index d681d904e74..4d76dba4c3a 100644 --- a/source/blender/editors/mesh/editmesh_intersect.c +++ b/source/blender/editors/mesh/editmesh_intersect.c @@ -33,6 +33,7 @@ #include "BLI_kdopbvh.h" #include "BLI_linklist_stack.h" +#include "BKE_layer.h" #include "BKE_editmesh_bvh.h" #include "BKE_context.h" #include "BKE_report.h" @@ -146,9 +147,6 @@ enum { static int edbm_intersect_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMesh *bm = em->bm; const int mode = RNA_enum_get(op->ptr, "mode"); int (*test_fn)(BMFace *, void *); bool use_separate_all = false; @@ -186,29 +184,45 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op) default: /* ISECT_SEPARATE_NONE */ break; } + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + uint isect_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); - has_isect = BM_mesh_intersect( - bm, - em->looptris, em->tottri, - test_fn, NULL, - use_self, use_separate_all, true, true, true, - -1, - eps); - - if (use_separate_cut) { - /* detach selected/un-selected faces */ - BM_mesh_separate_faces( - bm, - BM_elem_cb_check_hflag_enabled_simple(const BMFace *, BM_ELEM_SELECT)); - } + if (em->bm->totfacesel == 0) { + continue; + } + + has_isect = BM_mesh_intersect( + em->bm, + em->looptris, em->tottri, + test_fn, NULL, + use_self, use_separate_all, true, true, true, + -1, + eps); + + if (use_separate_cut) { + /* detach selected/un-selected faces */ + BM_mesh_separate_faces( + em->bm, + BM_elem_cb_check_hflag_enabled_simple(const BMFace *, BM_ELEM_SELECT)); + } - if (has_isect) { - edbm_intersect_select(em); + if (has_isect) { + edbm_intersect_select(em); + } + else { + isect_len++; + } } - else { + MEM_freeN(objects); + + if (isect_len == objects_len) { BKE_report(op->reports, RPT_WARNING, "No intersections found"); } - return OPERATOR_FINISHED; } @@ -266,9 +280,6 @@ void MESH_OT_intersect(struct wmOperatorType *ot) static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMesh *bm = em->bm; const int boolean_operation = RNA_enum_get(op->ptr, "operation"); bool use_swap = RNA_boolean_get(op->ptr, "use_swap"); const float eps = RNA_float_get(op->ptr, "threshold"); @@ -276,23 +287,39 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op) bool has_isect; test_fn = use_swap ? bm_face_isect_pair_swap : bm_face_isect_pair; + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + uint isect_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + + if (em->bm->totfacesel == 0) { + continue; + } - has_isect = BM_mesh_intersect( - bm, - em->looptris, em->tottri, - test_fn, NULL, - false, false, true, true, true, - boolean_operation, - eps); + has_isect = BM_mesh_intersect( + em->bm, + em->looptris, em->tottri, + test_fn, NULL, + false, false, true, true, true, + boolean_operation, + eps); - if (has_isect) { - edbm_intersect_select(em); + if (has_isect) { + edbm_intersect_select(em); + } + else { + isect_len++; + } } - else { + MEM_freeN(objects); + + if (isect_len == objects_len) { BKE_report(op->reports, RPT_WARNING, "No intersections found"); } - return OPERATOR_FINISHED; } @@ -652,257 +679,270 @@ static BMEdge *bm_face_split_edge_find( static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMesh *bm = em->bm; const char hflag = BM_ELEM_TAG; BMEdge *e; BMIter iter; - BLI_SMALLSTACK_DECLARE(loop_stack, BMLoop *); + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; - { - BMVert *v; - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - BM_elem_flag_disable(v, hflag); + if ((bm->totedgesel == 0) || + (bm->totfacesel == 0)) + { + continue; } - } - - /* edge index is set to -1 then used to assosiate them with faces */ - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e, BM_ELEM_SELECT) && BM_edge_is_wire(e)) { - BM_elem_flag_enable(e, hflag); - BM_elem_flag_enable(e->v1, hflag); - BM_elem_flag_enable(e->v2, hflag); + BLI_SMALLSTACK_DECLARE(loop_stack, BMLoop *); + { + BMVert *v; + BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_disable(v, hflag); + } } - else { - BM_elem_flag_disable(e, hflag); - } - BM_elem_index_set(e, -1); /* set_dirty */ - } - bm->elem_index_dirty |= BM_EDGE; - { - BMFace *f; - int i; - BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) { - if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { - BM_elem_flag_enable(f, hflag); + /* edge index is set to -1 then used to assosiate them with faces */ + BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_SELECT) && BM_edge_is_wire(e)) { + BM_elem_flag_enable(e, hflag); + + BM_elem_flag_enable(e->v1, hflag); + BM_elem_flag_enable(e->v2, hflag); + } else { - BM_elem_flag_disable(f, hflag); + BM_elem_flag_disable(e, hflag); } - BM_elem_flag_disable(f, BM_ELEM_INTERNAL_TAG); - BM_elem_index_set(f, i); /* set_ok */ + BM_elem_index_set(e, -1); /* set_dirty */ } - } - bm->elem_index_dirty &= ~BM_FACE; - - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e, hflag)) { - BMIter viter; - BMVert *v; - BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) { - BMIter liter; - BMLoop *l; - - unsigned int loop_stack_len; - BMLoop *l_best = NULL; - - BLI_assert(BLI_SMALLSTACK_IS_EMPTY(loop_stack)); - loop_stack_len = 0; - - BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - if (BM_elem_flag_test(l->f, hflag)) { - BLI_SMALLSTACK_PUSH(loop_stack, l); - loop_stack_len++; - } - } + bm->elem_index_dirty |= BM_EDGE; - if (loop_stack_len == 0) { - /* pass */ - } - else if (loop_stack_len == 1) { - l_best = BLI_SMALLSTACK_POP(loop_stack); + { + BMFace *f; + int i; + BM_ITER_MESH_INDEX(f, &iter, bm, BM_FACES_OF_MESH, i) { + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + BM_elem_flag_enable(f, hflag); } else { - /* complicated case, match the edge with a face-loop */ + BM_elem_flag_disable(f, hflag); + } + BM_elem_flag_disable(f, BM_ELEM_INTERNAL_TAG); + BM_elem_index_set(f, i); /* set_ok */ + } + } + bm->elem_index_dirty &= ~BM_FACE; + + BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, hflag)) { + BMIter viter; + BMVert *v; + BM_ITER_ELEM(v, &viter, e, BM_VERTS_OF_EDGE) { + BMIter liter; + BMLoop *l; + + unsigned int loop_stack_len; + BMLoop *l_best = NULL; + + BLI_assert(BLI_SMALLSTACK_IS_EMPTY(loop_stack)); + loop_stack_len = 0; + + BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { + if (BM_elem_flag_test(l->f, hflag)) { + BLI_SMALLSTACK_PUSH(loop_stack, l); + loop_stack_len++; + } + } + + if (loop_stack_len == 0) { + /* pass */ + } + else if (loop_stack_len == 1) { + l_best = BLI_SMALLSTACK_POP(loop_stack); + } + else { + /* complicated case, match the edge with a face-loop */ - BMVert *v_other = BM_edge_other_vert(e, v); - float e_dir[3]; + BMVert *v_other = BM_edge_other_vert(e, v); + float e_dir[3]; - /* we want closest to zero */ - float dot_best = FLT_MAX; + /* we want closest to zero */ + float dot_best = FLT_MAX; - sub_v3_v3v3(e_dir, v_other->co, v->co); - normalize_v3(e_dir); + sub_v3_v3v3(e_dir, v_other->co, v->co); + normalize_v3(e_dir); - while ((l = BLI_SMALLSTACK_POP(loop_stack))) { - float dot_test; + while ((l = BLI_SMALLSTACK_POP(loop_stack))) { + float dot_test; - /* Check dot first to save on expensive angle-comparison. - * ideal case is 90d difference == 0.0 dot */ - dot_test = fabsf(dot_v3v3(e_dir, l->f->no)); - if (dot_test < dot_best) { + /* Check dot first to save on expensive angle-comparison. + * ideal case is 90d difference == 0.0 dot */ + dot_test = fabsf(dot_v3v3(e_dir, l->f->no)); + if (dot_test < dot_best) { - /* check we're in the correct corner (works with convex loops too) */ - if (angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, v_other->co, l->f->no) < - angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, l->next->v->co, l->f->no)) - { - dot_best = dot_test; - l_best = l; + /* check we're in the correct corner (works with convex loops too) */ + if (angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, v_other->co, l->f->no) < + angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, l->next->v->co, l->f->no)) + { + dot_best = dot_test; + l_best = l; + } } } } - } - if (l_best) { - BM_elem_index_set(e, BM_elem_index_get(l_best->f)); /* set_dirty */ + if (l_best) { + BM_elem_index_set(e, BM_elem_index_get(l_best->f)); /* set_dirty */ + } } } } - } - { - BMFace *f; - BLI_buffer_declare_static(BMEdge **, edge_net_temp_buf, 0, 128); + { + BMFace *f; + BLI_buffer_declare_static(BMEdge **, edge_net_temp_buf, 0, 128); - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(f, hflag)) { - bm_face_split_by_edges(bm, f, hflag, &edge_net_temp_buf); + BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(f, hflag)) { + bm_face_split_by_edges(bm, f, hflag, &edge_net_temp_buf); + } } + BLI_buffer_free(&edge_net_temp_buf); } - BLI_buffer_free(&edge_net_temp_buf); - } #ifdef USE_NET_ISLAND_CONNECT - /* before overwriting edge index values, collect edges left untouched */ - BLI_Stack *edges_loose = BLI_stack_new(sizeof(BMEdge * ), __func__); - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e, BM_ELEM_SELECT) && BM_edge_is_wire(e)) { - BLI_stack_push(edges_loose, &e); + /* before overwriting edge index values, collect edges left untouched */ + BLI_Stack *edges_loose = BLI_stack_new(sizeof(BMEdge *), __func__); + BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_SELECT) && BM_edge_is_wire(e)) { + BLI_stack_push(edges_loose, &e); + } } - } #endif - EDBM_mesh_normals_update(em); - EDBM_update_generic(em, true, true); + EDBM_mesh_normals_update(em); + EDBM_update_generic(em, true, true); #ifdef USE_NET_ISLAND_CONNECT - /* we may have remaining isolated regions remaining, - * these will need to have connecting edges created */ - if (!BLI_stack_is_empty(edges_loose)) { - GHash *face_edge_map = BLI_ghash_ptr_new(__func__); + /* we may have remaining isolated regions remaining, + * these will need to have connecting edges created */ + if (!BLI_stack_is_empty(edges_loose)) { + GHash *face_edge_map = BLI_ghash_ptr_new(__func__); - MemArena *mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + MemArena *mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); - BM_mesh_elem_index_ensure(bm, BM_FACE); + BM_mesh_elem_index_ensure(bm, BM_FACE); - { - BMBVHTree *bmbvh = BKE_bmbvh_new(bm, em->looptris, em->tottri, BMBVH_RESPECT_SELECT, NULL, false); + { + BMBVHTree *bmbvh = BKE_bmbvh_new(bm, em->looptris, em->tottri, BMBVH_RESPECT_SELECT, NULL, false); - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - BM_elem_index_set(e, -1); /* set_dirty */ - } + BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) { + BM_elem_index_set(e, -1); /* set_dirty */ + } - while (!BLI_stack_is_empty(edges_loose)) { - BLI_stack_pop(edges_loose, &e); - float e_center[3]; - mid_v3_v3v3(e_center, e->v1->co, e->v2->co); + while (!BLI_stack_is_empty(edges_loose)) { + BLI_stack_pop(edges_loose, &e); + float e_center[3]; + mid_v3_v3v3(e_center, e->v1->co, e->v2->co); - BMFace *f = BKE_bmbvh_find_face_closest(bmbvh, e_center, FLT_MAX); - if (f) { - ghash_insert_face_edge_link(face_edge_map, f, e, mem_arena); - BM_elem_index_set(e, BM_elem_index_get(f)); /* set_dirty */ + BMFace *f = BKE_bmbvh_find_face_closest(bmbvh, e_center, FLT_MAX); + if (f) { + ghash_insert_face_edge_link(face_edge_map, f, e, mem_arena); + BM_elem_index_set(e, BM_elem_index_get(f)); /* set_dirty */ + } } - } - BKE_bmbvh_free(bmbvh); - } + BKE_bmbvh_free(bmbvh); + } - bm->elem_index_dirty |= BM_EDGE; + bm->elem_index_dirty |= BM_EDGE; - BM_mesh_elem_table_ensure(bm, BM_FACE); + BM_mesh_elem_table_ensure(bm, BM_FACE); - /* detect edges chains that span faces - * and splice vertices into the closest edges */ - { - GHashIterator gh_iter; - - GHASH_ITER(gh_iter, face_edge_map) { - BMFace *f = BLI_ghashIterator_getKey(&gh_iter); - struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter); - LinkNode *e_link = e_ls_base->list; - - do { - e = e_link->link; - - for (int j = 0; j < 2; j++) { - BMVert *v_pivot = (&e->v1)[j]; - /* checking that \a v_pivot isn't in the face - * prevents attempting to splice the same vertex into an edge from multiple faces */ - if (!BM_vert_in_face(v_pivot, f)) { - float v_pivot_co[3]; - float v_pivot_fac; - BMEdge *e_split = bm_face_split_edge_find( - e, f, v_pivot, bm->ftable, bm->totface, - v_pivot_co, &v_pivot_fac); - - if (e_split) { - /* for degenerate cases this vertex may be in one of this edges radial faces */ - if (!bm_vert_in_faces_radial(v_pivot, e_split, f)) { - BMEdge *e_new; - BMVert *v_new = BM_edge_split(bm, e_split, e_split->v1, &e_new, v_pivot_fac); - if (v_new) { - /* we _know_ these don't share an edge */ - BM_vert_splice(bm, v_pivot, v_new); - BM_elem_index_set(e_new, BM_elem_index_get(e_split)); + /* detect edges chains that span faces + * and splice vertices into the closest edges */ + { + GHashIterator gh_iter; + + GHASH_ITER(gh_iter, face_edge_map) { + BMFace *f = BLI_ghashIterator_getKey(&gh_iter); + struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter); + LinkNode *e_link = e_ls_base->list; + + do { + e = e_link->link; + + for (int j = 0; j < 2; j++) { + BMVert *v_pivot = (&e->v1)[j]; + /* checking that \a v_pivot isn't in the face + * prevents attempting to splice the same vertex into an edge from multiple faces */ + if (!BM_vert_in_face(v_pivot, f)) { + float v_pivot_co[3]; + float v_pivot_fac; + BMEdge *e_split = bm_face_split_edge_find( + e, f, v_pivot, bm->ftable, bm->totface, + v_pivot_co, &v_pivot_fac); + + if (e_split) { + /* for degenerate cases this vertex may be in one of this edges radial faces */ + if (!bm_vert_in_faces_radial(v_pivot, e_split, f)) { + BMEdge *e_new; + BMVert *v_new = BM_edge_split(bm, e_split, e_split->v1, &e_new, v_pivot_fac); + if (v_new) { + /* we _know_ these don't share an edge */ + BM_vert_splice(bm, v_pivot, v_new); + BM_elem_index_set(e_new, BM_elem_index_get(e_split)); + } } } } } - } - } while ((e_link = e_link->next)); + } while ((e_link = e_link->next)); + } } - } - { - MemArena *mem_arena_edgenet = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + { + MemArena *mem_arena_edgenet = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); - GHashIterator gh_iter; + GHashIterator gh_iter; - GHASH_ITER(gh_iter, face_edge_map) { - BMFace *f = BLI_ghashIterator_getKey(&gh_iter); - struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter); + GHASH_ITER(gh_iter, face_edge_map) { + BMFace *f = BLI_ghashIterator_getKey(&gh_iter); + struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter); - bm_face_split_by_edges_island_connect( - bm, f, - e_ls_base->list, e_ls_base->list_len, - mem_arena_edgenet); + bm_face_split_by_edges_island_connect( + bm, f, + e_ls_base->list, e_ls_base->list_len, + mem_arena_edgenet); - BLI_memarena_clear(mem_arena_edgenet); - } + BLI_memarena_clear(mem_arena_edgenet); + } - BLI_memarena_free(mem_arena_edgenet); - } + BLI_memarena_free(mem_arena_edgenet); + } - BLI_memarena_free(mem_arena); + BLI_memarena_free(mem_arena); - BLI_ghash_free(face_edge_map, NULL, NULL); + BLI_ghash_free(face_edge_map, NULL, NULL); - EDBM_mesh_normals_update(em); - EDBM_update_generic(em, true, true); - } + EDBM_mesh_normals_update(em); + EDBM_update_generic(em, true, true); + } - BLI_stack_free(edges_loose); + BLI_stack_free(edges_loose); #endif /* USE_NET_ISLAND_CONNECT */ + } + MEM_freeN(objects); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 0066afca540..41a0fa9ce38 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -3885,59 +3885,70 @@ void MESH_OT_edges_select_sharp(wmOperatorType *ot) static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMesh *bm = em->bm; - - BLI_LINKSTACK_DECLARE(stack, BMFace *); - - BMIter iter, liter, liter2; - BMFace *f; - BMLoop *l, *l2; + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); const float angle_limit_cos = cosf(RNA_float_get(op->ptr, "sharpness")); - BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); - - BLI_LINKSTACK_INIT(stack); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if ((BM_elem_flag_test(f, BM_ELEM_HIDDEN) != 0) || - (BM_elem_flag_test(f, BM_ELEM_TAG) != 0) || - (BM_elem_flag_test(f, BM_ELEM_SELECT) == 0)) - { + if (bm->totfacesel == 0) { continue; } - BLI_assert(BLI_LINKSTACK_SIZE(stack) == 0); + BLI_LINKSTACK_DECLARE(stack, BMFace *); - do { - BM_face_select_set(bm, f, true); + BMIter iter, liter, liter2; + BMFace *f; + BMLoop *l, *l2; - BM_elem_flag_enable(f, BM_ELEM_TAG); + BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BM_ITER_ELEM (l2, &liter2, l, BM_LOOPS_OF_LOOP) { - float angle_cos; + BLI_LINKSTACK_INIT(stack); - if (BM_elem_flag_test(l2->f, BM_ELEM_TAG) || - BM_elem_flag_test(l2->f, BM_ELEM_HIDDEN)) - { - continue; - } + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if ((BM_elem_flag_test(f, BM_ELEM_HIDDEN) != 0) || + (BM_elem_flag_test(f, BM_ELEM_TAG) != 0) || + (BM_elem_flag_test(f, BM_ELEM_SELECT) == 0)) + { + continue; + } + + BLI_assert(BLI_LINKSTACK_SIZE(stack) == 0); - angle_cos = dot_v3v3(f->no, l2->f->no); + do { + BM_face_select_set(bm, f, true); + + BM_elem_flag_enable(f, BM_ELEM_TAG); + + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + BM_ITER_ELEM (l2, &liter2, l, BM_LOOPS_OF_LOOP) { + float angle_cos; + + if (BM_elem_flag_test(l2->f, BM_ELEM_TAG) || + BM_elem_flag_test(l2->f, BM_ELEM_HIDDEN)) + { + continue; + } - if (angle_cos > angle_limit_cos) { - BLI_LINKSTACK_PUSH(stack, l2->f); + angle_cos = dot_v3v3(f->no, l2->f->no); + + if (angle_cos > angle_limit_cos) { + BLI_LINKSTACK_PUSH(stack, l2->f); + } } } - } - } while ((f = BLI_LINKSTACK_POP(stack))); - } + } while ((f = BLI_LINKSTACK_POP(stack))); + } - BLI_LINKSTACK_FREE(stack); + BLI_LINKSTACK_FREE(stack); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + } + MEM_freeN(objects); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index e8f3e592715..ab44e017fc6 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1030,7 +1030,7 @@ void EDBM_verts_mirror_cache_begin_ex( BM_mesh_elem_index_ensure(bm, BM_VERT); if (use_topology) { - ED_mesh_mirrtopo_init(me, NULL, &mesh_topo_store, true); + ED_mesh_mirrtopo_init__real_mesh(me, NULL, &mesh_topo_store, true); } else { tree = BLI_kdtree_new(bm->totvert); diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c index 22bfd8eedea..4c078d2ac8b 100644 --- a/source/blender/editors/mesh/mesh_mirror.c +++ b/source/blender/editors/mesh/mesh_mirror.c @@ -37,6 +37,8 @@ #include "BKE_DerivedMesh.h" #include "BLI_kdtree.h" #include "BKE_editmesh.h" +#include "BKE_library.h" +#include "BKE_mesh.h" #include "ED_mesh.h" @@ -93,7 +95,73 @@ int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, DerivedMesh *dm, co else { MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert; int i; - + + for (i = 0; i < totvert; i++, mvert++) { + BLI_kdtree_insert(MirrKdStore.tree, i, mvert->co); + } + } + + BLI_kdtree_balance(MirrKdStore.tree); + } + else if (mode == 'e') { /* end table */ + if (MirrKdStore.tree) { + BLI_kdtree_free(MirrKdStore.tree); + MirrKdStore.tree = NULL; + } + } + else { + BLI_assert(0); + } + + return 0; +} + +/* mode is 's' start, or 'e' end, or 'u' use */ +/* if end, ob can be NULL */ +int ED_mesh_mirror_spatial_table__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, const float co[3], char mode) +{ + if (mode == 'u') { /* use table */ + if (MirrKdStore.tree == NULL) + ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's'); + + if (MirrKdStore.tree) { + KDTreeNearest nearest; + const int i = BLI_kdtree_find_nearest(MirrKdStore.tree, co, &nearest); + + if (i != -1) { + if (nearest.dist < KD_THRESH) { + return i; + } + } + } + return -1; + } + else if (mode == 's') { /* start table */ + Mesh *me = ob->data; + const bool use_em = (!mesh && em && me->edit_btmesh == em); + const int totvert = use_em ? em->bm->totvert : mesh ? mesh->totvert : me->totvert; + + if (MirrKdStore.tree) /* happens when entering this call without ending it */ + ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, co, 'e'); + + MirrKdStore.tree = BLI_kdtree_new(totvert); + + if (use_em) { + BMVert *eve; + BMIter iter; + int i; + + /* this needs to be valid for index lookups later (callers need) */ + BM_mesh_elem_table_ensure(em->bm, BM_VERT); + + BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) { + BLI_kdtree_insert(MirrKdStore.tree, i, eve->co); + } + } + else { + MVert *mvert = mesh ? mesh->mvert : me->mvert; + int i; + for (i = 0; i < totvert; i++, mvert++) { BLI_kdtree_insert(MirrKdStore.tree, i, mvert->co); } @@ -172,11 +240,62 @@ bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, MirrTopoStore_t *m } } +bool ED_mesh_mirrtopo_recalc_check__real_mesh(Mesh *me, Mesh *dm, MirrTopoStore_t *mesh_topo_store) +{ + const bool is_editmode = (me->edit_btmesh != NULL); + int totvert; + int totedge; + + if (dm) { + totvert = dm->totvert; + totedge = dm->totedge; + } + else if (me->edit_btmesh) { + totvert = me->edit_btmesh->bm->totvert; + totedge = me->edit_btmesh->bm->totedge; + } + else { + totvert = me->totvert; + totedge = me->totedge; + } + + if ((mesh_topo_store->index_lookup == NULL) || + (mesh_topo_store->prev_is_editmode != is_editmode) || + (totvert != mesh_topo_store->prev_vert_tot) || + (totedge != mesh_topo_store->prev_edge_tot)) + { + return true; + } + else { + return false; + } + +} + void ED_mesh_mirrtopo_init( Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store, const bool skip_em_vert_array_init) { + Mesh *fake_mesh = NULL; + + if (dm != NULL) { + /* ED_real_mesh_mirrtopo_init() only uses the counts, not the actual data */ + fake_mesh = BKE_mesh_new_nomain(dm->getNumVerts(dm), dm->getNumEdges(dm), dm->getNumTessFaces(dm), + dm->getNumLoops(dm), dm->getNumPolys(dm)); + } + + ED_mesh_mirrtopo_init__real_mesh(me, fake_mesh, mesh_topo_store, skip_em_vert_array_init); + + if (dm != NULL) { + BKE_id_free(NULL, fake_mesh); + } +} + +void ED_mesh_mirrtopo_init__real_mesh( + Mesh *me, Mesh *dm, MirrTopoStore_t *mesh_topo_store, + const bool skip_em_vert_array_init) +{ const bool is_editmode = (me->edit_btmesh != NULL); MEdge *medge = NULL, *med; BMEditMesh *em = dm ? NULL : me->edit_btmesh; @@ -208,7 +327,7 @@ void ED_mesh_mirrtopo_init( totvert = em->bm->totvert; } else { - totvert = dm ? dm->getNumVerts(dm) : me->totvert; + totvert = dm ? dm->totvert : me->totvert; } topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr"); @@ -224,8 +343,8 @@ void ED_mesh_mirrtopo_init( } } else { - totedge = dm ? dm->getNumEdges(dm) : me->totedge; - medge = dm ? dm->getEdgeArray(dm) : me->medge; + totedge = dm ? dm->totedge : me->totedge; + medge = dm ? dm->medge : me->medge; for (a = 0, med = medge; a < totedge; a++, med++) { const unsigned int i1 = med->v1, i2 = med->v2; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 83458127820..9b86f904161 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -707,6 +707,30 @@ int ED_mesh_mirror_topo_table( return 0; } +/* mode is 's' start, or 'e' end, or 'u' use */ +/* if end, ob can be NULL */ +/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */ +int ED_mesh_mirror_topo_table__real_mesh( + Object *ob, Mesh *mesh, char mode) +{ + if (mode == 'u') { /* use table */ + if (ED_mesh_mirrtopo_recalc_check__real_mesh(ob->data, mesh, &mesh_topo_store)) { + ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 's'); + } + } + else if (mode == 's') { /* start table */ + ED_mesh_mirrtopo_init__real_mesh(ob->data, mesh, &mesh_topo_store, false); + } + else if (mode == 'e') { /* end table */ + ED_mesh_mirrtopo_free(&mesh_topo_store); + } + else { + BLI_assert(0); + } + + return 0; +} + /** \} */ @@ -742,6 +766,38 @@ int mesh_get_x_mirror_vert(Object *ob, DerivedMesh *dm, int index, const bool us } } +static int mesh_get_x_mirror_vert_spatial__real_mesh(Object *ob, Mesh *mesh, int index) +{ + Mesh *me = ob->data; + MVert *mvert = mesh ? mesh->mvert : me->mvert; + float vec[3]; + + mvert = &mvert[index]; + vec[0] = -mvert->co[0]; + vec[1] = mvert->co[1]; + vec[2] = mvert->co[2]; + + return ED_mesh_mirror_spatial_table__real_mesh(ob, NULL, mesh, vec, 'u'); +} + +static int mesh_get_x_mirror_vert_topo__real_mesh(Object *ob, Mesh *mesh, int index) +{ + if (ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 'u') == -1) + return -1; + + return mesh_topo_store.index_lookup[index]; +} + +int mesh_get_x_mirror_vert__real_mesh(Object *ob, Mesh *mesh, int index, const bool use_topology) +{ + if (use_topology) { + return mesh_get_x_mirror_vert_topo__real_mesh(ob, mesh, index); + } + else { + return mesh_get_x_mirror_vert_spatial__real_mesh(ob, mesh, index); + } +} + static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, const float co[3]) { float vec[3]; @@ -991,7 +1047,67 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm) BLI_ghash_free(fhash, NULL, NULL); MEM_freeN(mirrorverts); - + + return mirrorfaces; +} + +/* This is a Mesh-based copy of mesh_get_x_mirror_faces() */ +int *mesh_get_x_mirror_faces__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh) +{ + Mesh *me = ob->data; + MVert *mv, *mvert; + MFace mirrormf, *mf, *hashmf, *mface; + GHash *fhash; + int *mirrorverts, *mirrorfaces; + + BLI_assert(em == NULL); /* Does not work otherwise, currently... */ + + const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; + const int totvert = mesh ? mesh->totvert : me->totvert; + const int totface = mesh ? mesh->totface : me->totface; + int a; + + mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts"); + mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces"); + + mvert = mesh ? mesh->mvert : me->mvert; + mface = mesh ? mesh->mface : me->mface; + + ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's'); + + for (a = 0, mv = mvert; a < totvert; a++, mv++) + mirrorverts[a] = mesh_get_x_mirror_vert__real_mesh(ob, mesh, a, use_topology); + + ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 'e'); + + fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface); + for (a = 0, mf = mface; a < totface; a++, mf++) + BLI_ghash_insert(fhash, mf, mf); + + for (a = 0, mf = mface; a < totface; a++, mf++) { + mirrormf.v1 = mirrorverts[mf->v3]; + mirrormf.v2 = mirrorverts[mf->v2]; + mirrormf.v3 = mirrorverts[mf->v1]; + mirrormf.v4 = (mf->v4) ? mirrorverts[mf->v4] : 0; + + /* make sure v4 is not 0 if a quad */ + if (mf->v4 && mirrormf.v4 == 0) { + SWAP(unsigned int, mirrormf.v1, mirrormf.v3); + SWAP(unsigned int, mirrormf.v2, mirrormf.v4); + } + + hashmf = BLI_ghash_lookup(fhash, &mirrormf); + if (hashmf) { + mirrorfaces[a * 2] = hashmf - mface; + mirrorfaces[a * 2 + 1] = mirror_facerotation(&mirrormf, hashmf); + } + else + mirrorfaces[a * 2] = -1; + } + + BLI_ghash_free(fhash, NULL, NULL); + MEM_freeN(mirrorverts); + return mirrorfaces; } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index eb0492daf9c..6f8b50bb68a 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1629,9 +1629,17 @@ static void move_to_collection_menus_free(MoveToCollectionData **menu) static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout, void *menu_v) { MoveToCollectionData *menu = menu_v; + const char *name; + + if (menu->collection->flag & COLLECTION_IS_MASTER) { + name = IFACE_("Scene Collection"); + } + else { + name = menu->collection->id.name + 2; + } uiItemIntO(layout, - menu->collection->id.name + 2, + name, ICON_NONE, menu->ot->idname, "collection_index", diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 6a73e1912ab..3ac7a14753b 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2287,8 +2287,6 @@ static int make_override_static_exec(bContext *C, wmOperator *op) bool success = false; if (!ID_IS_LINKED(obact) && obact->dup_group != NULL && ID_IS_LINKED(obact->dup_group)) { - // TODO: support making the group itself override and putting - // it directly into the scene collections const ListBase dup_collection_objects = BKE_collection_object_cache_get(obact->dup_group); Base *base = BLI_findlink(&dup_collection_objects, RNA_enum_get(op->ptr, "object")); Object *obcollection = obact; @@ -2305,6 +2303,19 @@ static int make_override_static_exec(bContext *C, wmOperator *op) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + /* Then, we make static override of the whole set of objects in the collection. */ + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(collection, ob) + { + if (ob->type == OB_ARMATURE && ob->pose != NULL) { + for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) { + if (pchan->custom != NULL) { + pchan->custom->id.tag &= ~ LIB_TAG_DOIT; + } + } + } + } + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + success = BKE_override_static_create_from_tag(bmain); /* Intantiate our newly overridden objects in scene, if not yet done. */ @@ -2313,7 +2324,10 @@ static int make_override_static_exec(bContext *C, wmOperator *op) Collection *new_collection = (Collection *)collection->id.newid; FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(new_collection, new_ob) { - if (new_ob != NULL && (base = BKE_view_layer_base_find(view_layer, new_ob)) == NULL) { + if (new_ob != NULL && + new_ob->id.override_static != NULL && + (base = BKE_view_layer_base_find(view_layer, new_ob)) == NULL) + { BKE_collection_object_add_from(bmain, scene, obcollection, new_ob); DEG_id_tag_update_ex(bmain, &new_ob->id, OB_RECALC_OB | DEG_TAG_BASE_FLAGS_UPDATE); /* parent to 'collection' empty */ diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 3df934a8dca..e0427b4797c 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -55,6 +55,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_object.h" +#include "BKE_library.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_particle.h" @@ -364,7 +365,7 @@ typedef struct PEData { Scene *scene; ViewLayer *view_layer; Object *ob; - DerivedMesh *dm; + Mesh *mesh; PTCacheEdit *edit; BVHTreeFromMesh shape_bvh; Depsgraph *depsgraph; @@ -426,15 +427,15 @@ static void PE_set_view3d_data(bContext *C, PEData *data) static bool PE_create_shape_tree(PEData *data, Object *shapeob) { - DerivedMesh *dm = shapeob->derivedFinal; + Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_object(shapeob, 0); memset(&data->shape_bvh, 0, sizeof(data->shape_bvh)); - if (!dm) { + if (!mesh) { return false; } - return (bvhtree_from_mesh_get(&data->shape_bvh, dm, BVHTREE_FROM_LOOPTRI, 4) != NULL); + return (BKE_bvhtree_from_mesh_get(&data->shape_bvh, mesh, BVHTREE_FROM_LOOPTRI, 4) != NULL); } static void PE_free_shape_tree(PEData *data) @@ -641,9 +642,11 @@ static void foreach_mouse_hit_point(PEData *data, ForPointFunc func, int selecte static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected) { + Object *ob_eval = DEG_get_evaluated_object(data->depsgraph, data->ob); PTCacheEdit *edit = data->edit; ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd = NULL; + ParticleSystemModifierData *psmd_eval = NULL; ParticleEditSettings *pset= PE_settings(data->scene); POINT_P; KEY_K; float mat[4][4], imat[4][4]; @@ -654,6 +657,10 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected if (edit->psys) psmd= psys_get_modifier(data->ob, edit->psys); + if (psmd != NULL) { + psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name); + } + /* all is selected in path mode */ if (pset->selectmode==SCE_SELECT_PATH) selected= 0; @@ -667,7 +674,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected if (selected==0 || key->flag & PEK_SELECT) { if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); invert_m4_m4(imat, mat); } @@ -682,7 +689,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected if (selected==0 || key->flag & PEK_SELECT) { if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); invert_m4_m4(imat, mat); } @@ -769,7 +776,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) psmd= psys_get_modifier(ob, psys); totpart= psys->totpart; - if (!psmd->dm_final) + if (!psmd->mesh_final) return; tree= BLI_kdtree_new(totpart); @@ -777,7 +784,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) /* insert particles into kd tree */ LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd->mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); BLI_kdtree_insert(tree, p, co); @@ -791,7 +798,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd->mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); co[0] = -co[0]; @@ -817,7 +824,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) BLI_kdtree_free(tree); } -static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa) +static void PE_mirror_particle(Object *ob, Mesh *mesh, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa) { HairKey *hkey, *mhkey; PTCacheEditPoint *point, *mpoint; @@ -868,8 +875,8 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys } /* mirror positions and tags */ - psys_mat_hair_to_orco(ob, dm, psys->part->from, pa, mat); - psys_mat_hair_to_orco(ob, dm, psys->part->from, mpa, mmat); + psys_mat_hair_to_orco(ob, mesh, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, mesh, psys->part->from, mpa, mmat); invert_m4_m4(immat, mmat); hkey=pa->hair; @@ -906,7 +913,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) edit= psys->edit; psmd= psys_get_modifier(ob, psys); - if (!psmd->dm_final) + if (!psmd->mesh_final) return; if (!edit->mirror_cache) @@ -919,7 +926,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) * to avoid doing mirror twice */ LOOP_POINTS { if (point->flag & PEP_EDIT_RECALC) { - PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL); if (edit->mirror_cache[p] != -1) edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC; @@ -954,11 +961,11 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) psys = edit->psys; psmd = psys_get_modifier(ob, psys); - if (!psmd->dm_final) + if (!psmd->mesh_final) return; LOOP_EDITED_POINTS { - psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles + p, hairmat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles + p, hairmat); LOOP_KEYS { mul_m4_v3(hairmat, key->co); @@ -1105,12 +1112,12 @@ void recalc_emitter_field(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys { Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); ParticleSystem *psys_eval = psys_eval_get(depsgraph, ob, psys); - DerivedMesh *dm = psys_get_modifier(object_eval, psys_eval)->dm_final; + Mesh *mesh = psys_get_modifier(object_eval, psys_eval)->mesh_final; PTCacheEdit *edit = psys->edit; float *vec, *nor; int i, totface /*, totvert*/; - if (!dm) + if (!mesh) return; if (edit->emitter_cosnos) @@ -1118,7 +1125,7 @@ void recalc_emitter_field(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys BLI_kdtree_free(edit->emitter_field); - totface=dm->getNumTessFaces(dm); + totface = mesh->totface; /*totvert=dm->getNumVerts(dm);*/ /*UNSUED*/ edit->emitter_cosnos=MEM_callocN(totface*6*sizeof(float), "emitter cosnos"); @@ -1129,23 +1136,23 @@ void recalc_emitter_field(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys nor=vec+3; for (i=0; i<totface; i++, vec+=6, nor+=6) { - MFace *mface=dm->getTessFaceData(dm, i, CD_MFACE); + MFace *mface = &mesh->mface[i]; MVert *mvert; - mvert=dm->getVertData(dm, mface->v1, CD_MVERT); + mvert = &mesh->mvert[mface->v1]; copy_v3_v3(vec, mvert->co); VECCOPY(nor, mvert->no); - mvert=dm->getVertData(dm, mface->v2, CD_MVERT); + mvert = &mesh->mvert[mface->v2]; add_v3_v3v3(vec, vec, mvert->co); VECADD(nor, nor, mvert->no); - mvert=dm->getVertData(dm, mface->v3, CD_MVERT); + mvert = &mesh->mvert[mface->v3]; add_v3_v3v3(vec, vec, mvert->co); VECADD(nor, nor, mvert->no); if (mface->v4) { - mvert=dm->getVertData(dm, mface->v4, CD_MVERT); + mvert = &mesh->mvert[mface->v4]; add_v3_v3v3(vec, vec, mvert->co); VECADD(nor, nor, mvert->no); @@ -1208,12 +1215,12 @@ void update_world_cos(Depsgraph *depsgraph, Object *ob, PTCacheEdit *edit) psys_eval = psmd_eval->psys; } - if (psys == 0 || psys->edit == 0 || psmd_eval->dm_final == NULL) + if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL) return; LOOP_POINTS { if (!(psys->flag & PSYS_GLOBAL_HAIR)) - psys_mat_hair_to_global(ob_eval, psmd_eval->dm_final, psys->part->from, psys_eval->particles+p, hairmat); + psys_mat_hair_to_global(ob_eval, psmd_eval->mesh_final, psys->part->from, psys_eval->particles+p, hairmat); LOOP_KEYS { copy_v3_v3(key->world_co, key->co); @@ -1860,7 +1867,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool LOOP_VISIBLE_POINTS { if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR)) - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat); if (pset->selectmode==SCE_SELECT_POINT) { LOOP_KEYS { @@ -2305,7 +2312,7 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror) psmd= psys_get_modifier(ob, psys); LOOP_TAGGED_POINTS { - PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL); } } @@ -2385,7 +2392,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys) LOOP_POINTS { LOOP_TAGGED_KEYS { - PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL); break; } } @@ -2600,7 +2607,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* insert particles into kd tree */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); BLI_kdtree_insert(tree, p, co); @@ -2610,7 +2617,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* tag particles to be removed */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); @@ -2845,17 +2852,17 @@ static void PE_mirror_x( return; psmd= psys_get_modifier(ob, psys); - if (!psmd->dm_final) + if (!psmd->mesh_final) return; - const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly); + const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->mesh_final->runtime.deformed_only); /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */ BKE_mesh_tessface_ensure(me); - /* Note: In case psys uses DM tessface indices, we mirror final DM itself, not orig mesh. Avoids an (impossible) - * dm -> orig -> dm tessface indices conversion... */ - mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? psmd->dm_final : NULL); + /* Note: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. Avoids an (impossible) + * mesh -> orig -> mesh tessface indices conversion... */ + mirrorfaces = mesh_get_x_mirror_faces__real_mesh(ob, NULL, use_dm_final_indices ? psmd->mesh_final : NULL); if (!edit->mirror_cache) PE_update_mirror_cache(ob, psys); @@ -2869,7 +2876,7 @@ static void PE_mirror_x( if (point_is_selected(point)) { if (edit->mirror_cache[p] != -1) { /* already has a mirror, don't need to duplicate */ - PE_mirror_particle(ob, psmd->dm_final, psys, pa, NULL); + PE_mirror_particle(ob, psmd->mesh_final, psys, pa, NULL); continue; } else @@ -2882,7 +2889,7 @@ static void PE_mirror_x( } if (newtotpart != psys->totpart) { - MFace *mtessface = use_dm_final_indices ? psmd->dm_final->getTessFaceArray(psmd->dm_final) : me->mface; + MFace *mtessface = use_dm_final_indices ? psmd->mesh_final->mface : me->mface; /* allocate new arrays and copy existing */ new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new"); @@ -2951,7 +2958,7 @@ static void PE_mirror_x( } else { newpa->num_dmcache = psys_particle_dm_face_lookup( - psmd->dm_final, psmd->dm_deformed, newpa->num, newpa->fuv, NULL); + psmd->mesh_final, psmd->mesh_deformed, newpa->num, newpa->fuv, NULL); } /* update edit key pointers */ @@ -2962,7 +2969,7 @@ static void PE_mirror_x( } /* map key positions as mirror over x axis */ - PE_mirror_particle(ob, psmd->dm_final, psys, pa, newpa); + PE_mirror_particle(ob, psmd->mesh_final, psys, pa, newpa); newpa++; newpoint++; @@ -3172,7 +3179,7 @@ static void brush_puff(PEData *data, int point_index) } if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, psys->particles + point_index, mat); + psys_mat_hair_to_global(data->ob, data->mesh, psys->part->from, psys->particles + point_index, mat); invert_m4_m4(imat, mat); } else { @@ -3367,7 +3374,7 @@ static void intersect_dm_quad_weights(const float v1[3], const float v2[3], cons } /* check intersection with a derivedmesh */ -static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, DerivedMesh *dm, +static int particle_intersect_mesh(const bContext *C, Scene *scene, Object *ob, Mesh *mesh, float *vert_cos, const float co1[3], const float co2[3], float *min_d, int *min_face, float *min_w, @@ -3381,10 +3388,11 @@ static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, De float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3]; float cur_ipoint[3]; - if (dm == NULL) { + if (mesh == NULL) { psys_disable_all(ob); - dm = mesh_get_derived_final(depsgraph, scene, ob, 0); + /* TODO(Sybren): port to Mesh when we have decided how to handle derivedFinal and derivedDeform */ + DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, 0); if (dm == NULL) dm = mesh_get_derived_deform(depsgraph, scene, ob, 0); @@ -3392,10 +3400,13 @@ static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, De if (dm == NULL) return 0; + + mesh = BKE_id_new_nomain(ID_ME, NULL); + DM_to_mesh(dm, mesh, ob, CD_MASK_EVERYTHING, false); } /* BMESH_ONLY, deform dm may not have tessface */ - DM_ensure_tessface(dm); + BKE_mesh_tessface_ensure(mesh); if (pa_minmax==0) { @@ -3408,9 +3419,9 @@ static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, De copy_v3_v3(p_max, pa_minmax+3); } - totface=dm->getNumTessFaces(dm); - mface=dm->getTessFaceDataArray(dm, CD_MFACE); - mvert=dm->getVertDataArray(dm, CD_MVERT); + totface = mesh->totface; + mface = mesh->mface; + mvert = mesh->mvert; /* lets intersect the faces */ for (i=0; i<totface; i++, mface++) { @@ -3504,7 +3515,7 @@ static int brush_add(const bContext *C, PEData *data, short number) Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene= data->scene; Object *ob= data->ob; - DerivedMesh *dm; + Mesh *mesh; PTCacheEdit *edit = data->edit; ParticleSystem *psys= edit->psys; ParticleData *add_pars; @@ -3537,13 +3548,13 @@ static int brush_add(const bContext *C, PEData *data, short number) timestep= psys_get_timestep(&sim); - if (psys->part->use_modifier_stack || psmd->dm_final->deformedOnly) { - dm = psmd->dm_final; + if (psys->part->use_modifier_stack || psmd->mesh_final->runtime.deformed_only) { + mesh = psmd->mesh_final; } else { - dm = psmd->dm_deformed; + mesh = psmd->mesh_deformed; } - BLI_assert(dm); + BLI_assert(mesh); for (i=0; i<number; i++) { if (number>1) { @@ -3570,16 +3581,16 @@ static int brush_add(const bContext *C, PEData *data, short number) min_d=2.0; /* warning, returns the derived mesh face */ - if (particle_intersect_dm(C, scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) { - if (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly) { + if (particle_intersect_mesh(C, scene, ob, mesh, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) { + if (psys->part->use_modifier_stack && !psmd->mesh_final->runtime.deformed_only) { add_pars[n].num = add_pars[n].num_dmcache; add_pars[n].num_dmcache = DMCACHE_ISCHILD; } - else if (dm == psmd->dm_deformed) { + else if (mesh == psmd->mesh_deformed) { /* Final DM is not same topology as orig mesh, we have to map num_dmcache to real final dm. */ add_pars[n].num = add_pars[n].num_dmcache; add_pars[n].num_dmcache = psys_particle_dm_face_lookup( - psmd->dm_final, psmd->dm_deformed, + psmd->mesh_final, psmd->mesh_deformed, add_pars[n].num, add_pars[n].fuv, NULL); } else { @@ -3621,7 +3632,7 @@ static int brush_add(const bContext *C, PEData *data, short number) tree=BLI_kdtree_new(psys->totpart); for (i=0, pa=psys->particles; i<totpart; i++, pa++) { - psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0); + psys_particle_on_dm(psmd->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0); BLI_kdtree_insert(tree, i, cur_co); } @@ -3665,7 +3676,7 @@ static int brush_add(const bContext *C, PEData *data, short number) int w, maxw; float maxd, totw=0.0, weight[3]; - psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0); + psys_particle_on_dm(psmd->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0); maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3); maxd= ptn[maxw-1].dist; @@ -3730,7 +3741,7 @@ static int brush_add(const bContext *C, PEData *data, short number) } } for (k=0, hkey=pa->hair; k<pset->totaddkey; k++, hkey++) { - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); mul_m4_v3(imat, hkey->co); } @@ -3922,7 +3933,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_PUFF: { if (edit->psys) { - data.dm= psmd->dm_final; + data.mesh = psmd->mesh_final; data.mval= mval; data.rad= pe_brush_size_get(scene, brush); data.select= selected; @@ -3978,7 +3989,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_WEIGHT: { if (edit->psys) { - data.dm= psmd->dm_final; + data.mesh = psmd->mesh_final; data.mval= mval; data.rad= pe_brush_size_get(scene, brush); @@ -4325,7 +4336,7 @@ int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3]) LOOP_VISIBLE_POINTS { if (psys) - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat); LOOP_SELECTED_KEYS { copy_v3_v3(co, key->co); @@ -4363,7 +4374,7 @@ void PE_create_particle_edit( } /* no psmd->dm happens in case particle system modifier is not enabled */ - if (!(psys && psmd_eval && psmd_eval->dm_final) && !cache) + if (!(psys && psmd_eval && psmd_eval->mesh_final) && !cache) return; if (cache && cache->flag & PTCACHE_DISK_CACHE) diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 79d52abb32d..cb7c90a6c3d 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -33,6 +33,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_scene_types.h" @@ -48,6 +49,7 @@ #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_particle.h" @@ -574,7 +576,7 @@ static void disconnect_hair( point++; } - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat); for (k=0, key=pa->hair; k<pa->totkey; k++, key++) { mul_m4_v3(hairmat, key->co); @@ -653,13 +655,13 @@ static bool remap_hair_emitter( MFace *mface = NULL, *mf; MEdge *medge = NULL, *me; MVert *mvert; - DerivedMesh *dm, *target_dm; + Mesh *mesh, *target_mesh; int numverts; int i, k; float from_ob_imat[4][4], to_ob_imat[4][4]; float from_imat[4][4], to_imat[4][4]; - if (!target_psmd->dm_final) + if (!target_psmd->mesh_final) return false; if (!psys->part || psys->part->type != PART_HAIR) return false; @@ -673,40 +675,46 @@ static bool remap_hair_emitter( invert_m4_m4(from_imat, from_mat); invert_m4_m4(to_imat, to_mat); - if (target_psmd->dm_final->deformedOnly) { + if (target_psmd->mesh_final->runtime.deformed_only) { /* we don't want to mess up target_psmd->dm when converting to global coordinates below */ - dm = target_psmd->dm_final; + mesh = target_psmd->mesh_final; } else { - dm = target_psmd->dm_deformed; + mesh = target_psmd->mesh_deformed; } - target_dm = target_psmd->dm_final; - if (dm == NULL) { + target_mesh = target_psmd->mesh_final; + if (mesh == NULL) { return false; } /* don't modify the original vertices */ - dm = CDDM_copy(dm); + BKE_id_copy_ex( + NULL, &mesh->id, (ID **)&mesh, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); /* BMESH_ONLY, deform dm may not have tessface */ - DM_ensure_tessface(dm); + BKE_mesh_tessface_ensure(mesh); - numverts = dm->getNumVerts(dm); - mvert = dm->getVertArray(dm); + numverts = mesh->totvert; + mvert = mesh->mvert; /* convert to global coordinates */ for (i=0; i<numverts; i++) mul_m4_v3(to_mat, mvert[i].co); - if (dm->getNumTessFaces(dm) != 0) { - mface = dm->getTessFaceArray(dm); - bvhtree_from_mesh_get(&bvhtree, dm, BVHTREE_FROM_FACES, 2); + if (mesh->totface != 0) { + mface = mesh->mface; + BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_FACES, 2); } - else if (dm->getNumEdges(dm) != 0) { - medge = dm->getEdgeArray(dm); - bvhtree_from_mesh_get(&bvhtree, dm, BVHTREE_FROM_EDGES, 2); + else if (mesh->totedge != 0) { + medge = mesh->medge; + BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_EDGES, 2); } else { - dm->release(dm); + BKE_id_free(NULL, mesh); return false; } @@ -751,7 +759,7 @@ static bool remap_hair_emitter( tpa->foffset = 0.0f; tpa->num = nearest.index; - tpa->num_dmcache = psys_particle_dm_face_lookup(target_dm, dm, tpa->num, tpa->fuv, NULL); + tpa->num_dmcache = psys_particle_dm_face_lookup(target_mesh, mesh, tpa->num, tpa->fuv, NULL); } else { me = &medge[nearest.index]; @@ -777,7 +785,7 @@ static bool remap_hair_emitter( copy_m4_m4(imat, target_ob->obmat); else { /* note: using target_dm here, which is in target_ob object space and has full modifiers */ - psys_mat_hair_to_object(target_ob, target_dm, target_psys->part->from, tpa, hairmat); + psys_mat_hair_to_object(target_ob, target_mesh, target_psys->part->from, tpa, hairmat); invert_m4_m4(imat, hairmat); } mul_m4_m4m4(imat, imat, to_imat); @@ -823,7 +831,7 @@ static bool remap_hair_emitter( } free_bvhtree_from_mesh(&bvhtree); - dm->release(dm); + BKE_id_free(NULL, mesh); psys_free_path_cache(target_psys, target_edit); @@ -994,7 +1002,7 @@ static bool copy_particle_systems_to_object(const bContext *C, ModifierData *md; ParticleSystem *psys_start = NULL, *psys, *psys_from; ParticleSystem **tmp_psys; - DerivedMesh *final_dm; + Mesh *final_mesh; CustomDataMask cdmask; int i, totpsys; @@ -1036,8 +1044,11 @@ static bool copy_particle_systems_to_object(const bContext *C, psys_start = totpsys > 0 ? tmp_psys[0] : NULL; /* get the DM (psys and their modifiers have not been appended yet) */ - final_dm = mesh_get_derived_final(depsgraph, scene, ob_to, cdmask); - + /* TODO(Sybren): use mesh_evaluated instead */ + DerivedMesh *final_dm = mesh_get_derived_final(depsgraph, scene, ob_to, cdmask); + final_mesh = BKE_id_new_nomain(ID_ME, NULL); + DM_to_mesh(final_dm, final_mesh, ob_to, CD_MASK_EVERYTHING, false); + /* now append psys to the object and make modifiers */ for (i = 0, psys_from = PSYS_FROM_FIRST; i < totpsys; @@ -1060,10 +1071,17 @@ static bool copy_particle_systems_to_object(const bContext *C, modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd); psmd->psys = psys; - psmd->dm_final = CDDM_copy(final_dm); - CDDM_calc_normals(psmd->dm_final); - DM_ensure_tessface(psmd->dm_final); - + BKE_id_copy_ex( + NULL, &final_mesh->id, (ID **)&psmd->mesh_final, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); + + BKE_mesh_calc_normals(psmd->mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); + if (psys_from->edit) { copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 8ebdb5f32b8..7167b48c06e 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -848,6 +848,7 @@ void ED_screens_initialize(wmWindowManager *wm) ED_screen_global_areas_create(win); } ED_screen_refresh(wm, win); + ED_screen_set_active_region(NULL, win, &win->eventstate->x); } } @@ -992,9 +993,8 @@ static void screen_cursor_set(wmWindow *win, const int xy[2]) /* called in wm_event_system.c. sets state vars in screen, cursors */ /* event type is mouse move */ -void ED_screen_set_active_region(bContext *C, const int xy[2]) +void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) { - wmWindow *win = CTX_wm_window(C); bScreen *scr = WM_window_get_active_screen(win); if (scr) { @@ -1058,7 +1058,9 @@ void ED_screen_set_active_region(bContext *C, const int xy[2]) /* this used to be a notifier, but needs to be done immediate * because it can undo setting the right button as active due * to delayed notifier handling */ - UI_screen_free_active_but(C, scr); + if (C) { + UI_screen_free_active_but(C, scr); + } } else region_cursor_set(win, false); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index fd8fe84cffc..a1435d5916a 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -5761,7 +5761,7 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) /* api callbacks */ ot->invoke = texture_paint_add_texture_paint_slot_invoke; ot->exec = texture_paint_add_texture_paint_slot_exec; - ot->poll = ED_operator_region_view3d_active; + ot->poll = ED_operator_object_active; /* flags */ ot->flag = OPTYPE_UNDO; diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index e0041d36a24..206cdd57342 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -65,7 +65,7 @@ bool outliner_is_collection_tree_element(const TreeElement *te) return false; } - if (tselem->type == TSE_LAYER_COLLECTION) { + if (ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) { return true; } else if (tselem->type == 0 && te->idcode == ID_GR) { @@ -87,7 +87,7 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te) LayerCollection *lc = te->directdata; return lc->collection; } - else if (ELEM(tselem->type, TSE_R_LAYER, TSE_SCENE_COLLECTION_BASE)) { + else if (ELEM(tselem->type, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) { Scene *scene = (Scene*)tselem->id; return BKE_collection_master(scene); } @@ -104,7 +104,7 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te) static int collections_editor_poll(bContext *C) { SpaceOops *so = CTX_wm_space_outliner(C); - return (so != NULL) && ELEM(so->outlinevis, SO_COLLECTIONS, SO_VIEW_LAYER, SO_SCENES); + return (so != NULL) && ELEM(so->outlinevis, SO_VIEW_LAYER, SO_SCENES); } @@ -145,19 +145,17 @@ static int collection_new_exec(bContext *C, wmOperator *op) .collection = NULL, }; - outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_selected_to_add, &data); + if (RNA_boolean_get(op->ptr, "nested")) { + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_selected_to_add, &data); - if (data.error) { - BKE_report(op->reports, RPT_ERROR, "More than one collection is selected"); - return OPERATOR_CANCELLED; + if (data.error) { + BKE_report(op->reports, RPT_ERROR, "More than one collection is selected"); + return OPERATOR_CANCELLED; + } } - if (!data.collection) { - if (!(soops->outlinevis == SO_COLLECTIONS && - ELEM(soops->filter_collection, SO_FILTER_COLLECTION_UNLINKED, SO_FILTER_COLLECTION_ALL))) - { - data.collection = BKE_collection_master(scene); - } + if (!data.collection && (soops->outlinevis == SO_VIEW_LAYER)) { + data.collection = BKE_collection_master(scene); } BKE_collection_add( @@ -184,6 +182,10 @@ void OUTLINER_OT_collection_new(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + PropertyRNA *prop = RNA_def_boolean(ot->srna, "nested", true, "Nested", "Add as child of selected collection");; + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /**************************** Delete Collection ******************************/ @@ -265,7 +267,8 @@ void OUTLINER_OT_collection_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "hierarchy", false, "Hierarchy", "Delete child objects and collections"); + PropertyRNA *prop = RNA_def_boolean(ot->srna, "hierarchy", false, "Hierarchy", "Delete child objects and collections"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /****************************** Select Objects *******************************/ @@ -285,6 +288,8 @@ static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeEle data->layer_collection = te->directdata; return TRAVERSE_BREAK; case TSE_R_LAYER: + case TSE_SCENE_COLLECTION_BASE: + case TSE_VIEW_COLLECTION_BASE: return TRAVERSE_CONTINUE; default: return TRAVERSE_SKIP_CHILDS; @@ -365,6 +370,8 @@ static TreeTraversalAction outliner_find_first_selected_collection(TreeElement * data->te = te; return TRAVERSE_BREAK; case TSE_R_LAYER: + case TSE_SCENE_COLLECTION_BASE: + case TSE_VIEW_COLLECTION_BASE: default: return TRAVERSE_CONTINUE; } @@ -400,7 +407,7 @@ static int collection_duplicate_exec(bContext *C, wmOperator *op) switch (soops->outlinevis) { case SO_SCENES: case SO_VIEW_LAYER: - case SO_COLLECTIONS: + case SO_LIBRARIES: BKE_collection_copy(bmain, parent, collection); break; } @@ -538,3 +545,153 @@ void OUTLINER_OT_collection_instance(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +/************************** Exclude Collection ******************************/ + +static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, void *customdata) +{ + struct CollectionEditData *data = customdata; + TreeStoreElem *tselem = TREESTORE(te); + + if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) { + return TRAVERSE_CONTINUE; + } + + LayerCollection *lc = te->directdata; + + if (lc->collection->flag & COLLECTION_IS_MASTER) { + /* skip - showing warning/error message might be missleading + * when deleting multiple collections, so just do nothing */ + } + else { + /* Delete, duplicate and link don't edit children, those will come along + * with the parents. */ + BLI_gset_add(data->collections_to_edit, lc); + } + + return TRAVERSE_CONTINUE; +} + +static int collections_view_layer_poll(bContext *C, bool include) +{ + /* Poll function so the right click menu show current state of selected collections. */ + SpaceOops *soops = CTX_wm_space_outliner(C); + if (!(soops && soops->outlinevis == SO_VIEW_LAYER)) { + return false; + } + + Scene *scene = CTX_data_scene(C); + struct CollectionEditData data = {.scene = scene, .soops = soops}; + data.collections_to_edit = BLI_gset_ptr_new(__func__); + bool result = false; + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data); + + GSetIterator collections_to_edit_iter; + GSET_ITER(collections_to_edit_iter, data.collections_to_edit) { + LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter); + + if (include && (lc->flag & LAYER_COLLECTION_EXCLUDE)) { + result = true; + } + else if (!include && !(lc->flag & LAYER_COLLECTION_EXCLUDE)) { + result = true; + } + } + + BLI_gset_free(data.collections_to_edit, NULL); + return result; +} + +static int collections_exclude_poll(bContext *C) +{ + return collections_view_layer_poll(C, false); +} + +static int collections_include_poll(bContext *C) +{ + return collections_view_layer_poll(C, true); +} + +static void layer_collection_exclude_recursive_set(LayerCollection *lc) +{ + for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { + if (lc->flag & LAYER_COLLECTION_EXCLUDE) { + nlc->flag |= LAYER_COLLECTION_EXCLUDE; + } + else { + nlc->flag &= ~LAYER_COLLECTION_EXCLUDE; + } + + layer_collection_exclude_recursive_set(nlc); + } +} + +static int collection_view_layer_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + struct CollectionEditData data = {.scene = scene, .soops = soops}; + bool include = STREQ(op->idname, "OUTLINER_OT_collection_include_set"); + + data.collections_to_edit = BLI_gset_ptr_new(__func__); + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data); + + GSetIterator collections_to_edit_iter; + GSET_ITER(collections_to_edit_iter, data.collections_to_edit) { + LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter); + + if (!(lc->collection->flag & COLLECTION_IS_MASTER)) { + if (include) { + lc->flag &= ~LAYER_COLLECTION_EXCLUDE; + } + else { + lc->flag |= LAYER_COLLECTION_EXCLUDE; + } + + layer_collection_exclude_recursive_set(lc); + } + } + + BLI_gset_free(data.collections_to_edit, NULL); + + BKE_layer_collection_sync(scene, view_layer); + DEG_relations_tag_update(bmain); + + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Exclude from View Layer"; + ot->idname = "OUTLINER_OT_collection_exclude_set"; + ot->description = "Exclude collection from the active view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_exclude_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void OUTLINER_OT_collection_include_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Include in View Layer"; + ot->idname = "OUTLINER_OT_collection_include_set"; + ot->description = "Include collection in the active view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_include_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index d92b5df56be..90b137bcd7d 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -262,38 +262,6 @@ static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void } } -static void layer_collection_exclude_recursive_set(LayerCollection *lc) -{ - for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { - if (lc->flag & LAYER_COLLECTION_EXCLUDE) { - nlc->flag |= LAYER_COLLECTION_EXCLUDE; - } - else { - nlc->flag &= ~LAYER_COLLECTION_EXCLUDE; - } - - layer_collection_exclude_recursive_set(nlc); - } -} - -static void layer_collection_exclude_cb(bContext *C, void *poin, void *poin2) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = (Scene *)poin; - LayerCollection *lc = (LayerCollection *)poin2; - ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc); - - layer_collection_exclude_recursive_set(lc); - - BKE_layer_collection_sync(scene, view_layer); - - /* TODO(sergey): Use proper flag for tagging here. */ - DEG_id_tag_update(&scene->id, 0); - DEG_relations_tag_update(bmain); - WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL); -} - - static void namebutton_cb(bContext *C, void *tsep, char *oldname) { Main *bmain = CTX_data_main(C); @@ -423,10 +391,6 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, gpd); break; } - case TSE_R_LAYER: - { - break; - } case TSE_LAYER_COLLECTION: { BLI_libblock_ensure_unique_name(bmain, tselem->id->name); @@ -450,15 +414,12 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar PropertyRNA *collection_prop_hide_viewport; PropertyRNA *collection_prop_hide_select; PropertyRNA *collection_prop_hide_render; - PropertyRNA *collection_prop_exclude; collection_prop_hide_select = RNA_struct_type_find_property(&RNA_Collection, "hide_select"); collection_prop_hide_viewport = RNA_struct_type_find_property(&RNA_Collection, "hide_viewport"); collection_prop_hide_render = RNA_struct_type_find_property(&RNA_Collection, "hide_render"); - collection_prop_exclude = RNA_struct_type_find_property(&RNA_LayerCollection, "use"); BLI_assert(collection_prop_hide_viewport && collection_prop_hide_select && - collection_prop_hide_render && - collection_prop_exclude); + collection_prop_hide_render); for (te = lb->first; te; te = te->next) { tselem = TREESTORE(te); @@ -568,20 +529,9 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar UI_block_emboss_set(block, UI_EMBOSS_NONE); - if (soops->outlinevis == SO_VIEW_LAYER) { - if (lc && !(collection->flag & COLLECTION_IS_MASTER)) { - PointerRNA layer_collection_ptr; - RNA_pointer_create(&scene->id, &RNA_LayerCollection, lc, &layer_collection_ptr); - - bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, - (lc->flag & LAYER_COLLECTION_EXCLUDE) ? ICON_CHECKBOX_DEHLT : ICON_CHECKBOX_HLT, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, - UI_UNIT_Y, &layer_collection_ptr, collection_prop_exclude, -1, 0, 0, 0, 0, NULL); - UI_but_func_set(bt, layer_collection_exclude_cb, scene, lc); - UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - } - } - else if (!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) { + if ((!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) && + !(collection->flag & COLLECTION_IS_MASTER)) + { PointerRNA collection_ptr; RNA_id_pointer_create(&collection->id, &collection_ptr); @@ -1111,6 +1061,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto break; case TSE_LAYER_COLLECTION: case TSE_SCENE_COLLECTION_BASE: + case TSE_VIEW_COLLECTION_BASE: ICON_DRAW(ICON_GROUP); break; /* Removed the icons from outliner. Need a better structure with Layers, Palettes and Colors */ @@ -1249,6 +1200,11 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto } break; } + case ID_BR: + tselem_draw_icon_uibut(&arg, ICON_BRUSH_DATA); break; + case ID_SCR: + case ID_WS: + tselem_draw_icon_uibut(&arg, ICON_SPLITSCREEN); break; default: break; } @@ -1320,10 +1276,11 @@ static void outliner_draw_iconrow( } /* this tree element always has same amount of branches, so don't draw */ - if (tselem->type != TSE_R_LAYER) + if (tselem->type != TSE_R_LAYER) { outliner_draw_iconrow( C, block, scene, view_layer, obedit, soops, &te->subtree, level + 1, xmax, offsx, ys, alpha_fac); + } } } @@ -1442,8 +1399,8 @@ static void outliner_draw_tree_element( te->flag |= TE_ACTIVE; // for lookup in display hierarchies } - if (tselem->type == TSE_R_LAYER && ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS, SO_OBJECTS)) { - /* View layer in collections can't expand/collapse. */ + if (tselem->type == TSE_VIEW_COLLECTION_BASE) { + /* Scene collection in view layer can't expand/collapse. */ } else if (te->subtree.first || (tselem->type == 0 && te->idcode == ID_SCE) || (te->flag & TE_LAZY_CLOSED)) { /* open/close icon, only when sublevels, except for scene */ @@ -1461,7 +1418,7 @@ static void outliner_draw_tree_element( /* datatype icon */ - if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) { + if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) { tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac); offsx += UI_UNIT_X + 2 * ufac; } @@ -1746,7 +1703,7 @@ static void outliner_draw_highlights_recursive( int start_x, int *io_start_y) { const bool is_searching = SEARCHING_OUTLINER(soops) || - (soops->outlinevis == SO_DATABLOCKS && + (soops->outlinevis == SO_DATA_API && (soops->filter & SO_FILTER_SEARCH) && soops->search_string[0] != 0); @@ -1814,7 +1771,7 @@ static void outliner_draw_tree( glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // only once - if (soops->outlinevis == SO_DATABLOCKS) { + if (soops->outlinevis == SO_DATA_API) { /* struct marks */ starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET; outliner_draw_struct_marks(ar, soops, &soops->tree, &starty); @@ -1940,7 +1897,7 @@ void draw_outliner(const bContext *C) /* get extents of data */ outliner_height(soops, &soops->tree, &sizey); - if (soops->outlinevis == SO_DATABLOCKS) { + if (soops->outlinevis == SO_DATA_API) { /* RNA has two columns: * - column 1 is (max_width + OL_RNA_COL_SPACEX) or * (OL_RNA_COL_X), whichever is wider... @@ -1990,7 +1947,7 @@ void draw_outliner(const bContext *C) (bContext *)C, block, scene, view_layer, obedit, ar, soops, has_restrict_icons, &te_edit); - if (soops->outlinevis == SO_DATABLOCKS) { + if (soops->outlinevis == SO_DATA_API) { /* draw rna buttons */ outliner_draw_rnacols(ar, sizex_rna); outliner_draw_rnabuts(block, ar, soops, sizex_rna, &soops->tree); diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 4bb2f49fd08..5922e208f36 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -264,7 +264,8 @@ static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem, /* do nothing */; } else if (ELEM(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, - TSE_DRIVER_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE)) + TSE_DRIVER_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_SCENE_COLLECTION_BASE, + TSE_VIEW_COLLECTION_BASE)) { BKE_report(reports, RPT_WARNING, "Cannot edit builtin name"); } @@ -1338,7 +1339,7 @@ static int ed_operator_outliner_datablocks_active(bContext *C) ScrArea *sa = CTX_wm_area(C); if ((sa) && (sa->spacetype == SPACE_OUTLINER)) { SpaceOops *so = CTX_wm_space_outliner(C); - return (so->outlinevis == SO_DATABLOCKS); + return (so->outlinevis == SO_DATA_API); } return 0; } @@ -2063,7 +2064,12 @@ static int outliner_parenting_poll(bContext *C) SpaceOops *soops = CTX_wm_space_outliner(C); if (soops) { - if (ELEM(soops->outlinevis, SO_SCENES, SO_OBJECTS)) { + if (soops->outlinevis == SO_SCENES) { + return true; + } + else if ((soops->outlinevis == SO_VIEW_LAYER) && + (soops->filter & SO_FILTER_NO_COLLECTION)) + { return true; } } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 86208dcb22d..73494b890ed 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -163,7 +163,7 @@ typedef enum { /* The outliner display modes that support the filter system. * Note: keep it synced with space_outliner.py */ -#define SUPPORT_FILTER_OUTLINER(soops_) (ELEM((soops_)->outlinevis, SO_COLLECTIONS, SO_OBJECTS)) +#define SUPPORT_FILTER_OUTLINER(soops_) (ELEM((soops_)->outlinevis, SO_VIEW_LAYER)) /* Outliner Searching -- * @@ -345,6 +345,8 @@ void OUTLINER_OT_collection_objects_select(struct wmOperatorType *ot); void OUTLINER_OT_collection_objects_deselect(struct wmOperatorType *ot); void OUTLINER_OT_collection_link(struct wmOperatorType *ot); void OUTLINER_OT_collection_instance(struct wmOperatorType *ot); +void OUTLINER_OT_collection_exclude_set(struct wmOperatorType *ot); +void OUTLINER_OT_collection_include_set(struct wmOperatorType *ot); /* outliner_utils.c ---------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index d7a158b92a6..9c1b9bf2630 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -69,7 +69,7 @@ static int outliner_item_drag_drop_poll(bContext *C) SpaceOops *soops = CTX_wm_space_outliner(C); return ED_operator_outliner_active(C) && /* Only collection display modes supported for now. Others need more design work */ - ELEM(soops->outlinevis, SO_COLLECTIONS, SO_OBJECTS); + ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_LIBRARIES); } static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event) @@ -455,6 +455,8 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_collection_objects_deselect); WM_operatortype_append(OUTLINER_OT_collection_link); WM_operatortype_append(OUTLINER_OT_collection_instance); + WM_operatortype_append(OUTLINER_OT_collection_exclude_set); + WM_operatortype_append(OUTLINER_OT_collection_include_set); } static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf) diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 810b7815214..42fe70be527 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -681,6 +681,27 @@ static eOLDrawState tree_element_active_keymap_item( return OL_DRAWSEL_NONE; } +static eOLDrawState tree_element_active_master_collection( + bContext *C, TreeElement *UNUSED(te), const eOLSetState set) +{ + if (set == OL_SETSEL_NONE) { + ViewLayer *view_layer = CTX_data_view_layer(C); + LayerCollection *active = CTX_data_layer_collection(C); + + if (active == view_layer->layer_collections.first) { + return OL_DRAWSEL_NORMAL; + } + } + else { + ViewLayer *view_layer = CTX_data_view_layer(C); + LayerCollection *layer_collection = view_layer->layer_collections.first; + BKE_layer_collection_activate(view_layer, layer_collection); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + } + + return OL_DRAWSEL_NONE; +} + static eOLDrawState tree_element_active_layer_collection( bContext *C, TreeElement *te, const eOLSetState set) { @@ -695,7 +716,7 @@ static eOLDrawState tree_element_active_layer_collection( Scene *scene = CTX_data_scene(C); LayerCollection *layer_collection = te->directdata; ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection); - view_layer->active_collection = layer_collection; + BKE_layer_collection_activate(view_layer, layer_collection); WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); } @@ -763,12 +784,7 @@ eOLDrawState tree_element_type_active( case TSE_CONSTRAINT: return tree_element_active_constraint(C, scene, view_layer, te, tselem, set); case TSE_R_LAYER: - if (soops->outlinevis == SO_SCENES) { - return active_viewlayer(C, scene, view_layer, te, tselem, set); - } - else { - return OL_DRAWSEL_NONE; - } + return active_viewlayer(C, scene, view_layer, te, tselem, set); case TSE_POSEGRP: return tree_element_active_posegroup(C, scene, view_layer, te, tselem, set); case TSE_SEQUENCE: @@ -780,6 +796,8 @@ eOLDrawState tree_element_type_active( case TSE_GP_LAYER: //return tree_element_active_gplayer(C, scene, s, te, tselem, set); break; + case TSE_VIEW_COLLECTION_BASE: + return tree_element_active_master_collection(C, te, set); case TSE_LAYER_COLLECTION: return tree_element_active_layer_collection(C, te, set); } @@ -905,7 +923,7 @@ static bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_ static bool outliner_is_co_within_restrict_columns(const SpaceOops *soops, const ARegion *ar, float view_co_x) { - return ((soops->outlinevis != SO_DATABLOCKS) && + return ((soops->outlinevis != SO_DATA_API) && !(soops->flag & SO_HIDE_RESTRICTCOLS) && (view_co_x > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX)); } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 6ee8b354772..5ae6cec84ba 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -105,11 +105,8 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb, for (te = lb->first; te; te = te->next) { tselem = TREESTORE(te); if (tselem->flag & TSE_SELECTED) { - if (tselem->type == TSE_R_LAYER && soops->outlinevis == SO_COLLECTIONS) { - /* Don't let immutable render layer item affect menu. */ - } - else if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) { - /* Layer collection points to collection ID. */ + /* Layer collection points to collection ID. */ + if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) { if (*datalevel == 0) *datalevel = tselem->type; else if (*datalevel != tselem->type) @@ -133,6 +130,9 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb, case ID_LI: if (*idlevel == 0) *idlevel = idcode; else if (*idlevel != idcode) *idlevel = -1; + if (ELEM(*datalevel, TSE_VIEW_COLLECTION_BASE, TSE_SCENE_COLLECTION_BASE)) { + *datalevel = 0; + } break; } } @@ -1824,12 +1824,9 @@ static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soop else if (datalevel == TSE_LAYER_COLLECTION) { WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN); } - else if (datalevel == TSE_R_LAYER && ELEM(soops->outlinevis, SO_COLLECTIONS, SO_VIEW_LAYER)) { + else if (ELEM(datalevel, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) { WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN); } - else if (ELEM(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER)) { - /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/ - } else if (datalevel == TSE_ID_BASE) { /* do nothing... there are no ops needed here yet */ } @@ -1880,7 +1877,7 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent if (!found) { /* Menus for clicking in empty space. */ - if (ELEM(soops->outlinevis, SO_COLLECTIONS, SO_VIEW_LAYER)) { + if (soops->outlinevis == SO_VIEW_LAYER) { WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN); } } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 22d70a12261..58ab8f3735e 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -299,7 +299,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s /* Collections */ ten = outliner_add_element(soops, lb, &sce->id, te, TSE_SCENE_COLLECTION_BASE, 0); - ten->name = IFACE_("Collections"); + ten->name = IFACE_("Scene Collection"); outliner_add_collection_recursive(soops, sce->master_collection, ten); /* Objects */ @@ -877,7 +877,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i else if (type == TSE_GP_LAYER) { /* pass */ } - else if (ELEM(type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION_BASE)) { + else if (ELEM(type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) { /* pass */ } else if (type == TSE_ID_BASE) { @@ -896,8 +896,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL; /* ID datablock */ - if (tsepar == NULL || tsepar->type != TSE_ID_BASE) + if (tsepar == NULL || tsepar->type != TSE_ID_BASE || soops->filter_id_type) { outliner_add_id_contents(soops, te, tselem, id); + } } else if (type == TSE_ANIM_DATA) { IdAdtTemplate *iat = (IdAdtTemplate *)idv; @@ -1252,16 +1253,56 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t /* ----------------------------------------------- */ +static const char *outliner_idcode_to_plural(short idcode) +{ + const char *propname = BKE_idcode_to_name_plural(idcode); + PropertyRNA *prop = RNA_struct_type_find_property(&RNA_BlendData, propname); + return (prop) ? RNA_property_ui_name(prop) : "UNKNOWN"; +} + +static bool outliner_library_id_show(Library *lib, ID *id, short filter_id_type) +{ + if (id->lib != lib) { + return false; + } + + if (filter_id_type == ID_GR) { + /* Don't show child collections of non-scene master collection, + * they are already shown as children. */ + Collection *collection = (Collection *)id; + bool has_non_scene_parent = false; + + for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) { + if (!(cparent->collection->flag & COLLECTION_IS_MASTER)) { + has_non_scene_parent = true; + } + } + + if (has_non_scene_parent) { + return false; + } + } + + return true; +} static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeElement *te, Library *lib) { TreeElement *ten; ListBase *lbarray[MAX_LIBARRAY]; int a, tot; + short filter_id_type = (soops->filter & SO_FILTER_ID_TYPE) ? soops->filter_id_type : 0; - tot = set_listbasepointers(mainvar, lbarray); + if (filter_id_type) { + lbarray[0] = which_libbase(mainvar, soops->filter_id_type); + tot = 1; + } + else { + tot = set_listbasepointers(mainvar, lbarray); + } + for (a = 0; a < tot; a++) { - if (lbarray[a]->first) { + if (lbarray[a] && lbarray[a]->first) { ID *id = lbarray[a]->first; /* check if there's data in current lib */ @@ -1270,21 +1311,23 @@ static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeE break; if (id) { - ten = outliner_add_element(soops, &te->subtree, lbarray[a], NULL, TSE_ID_BASE, 0); - ten->directdata = lbarray[a]; - - ten->name = BKE_idcode_to_name_plural(GS(id->name)); - if (ten->name == NULL) - ten->name = "UNKNOWN"; + if (filter_id_type) { + ten = te; + } + else { + ten = outliner_add_element(soops, &te->subtree, lbarray[a], NULL, TSE_ID_BASE, 0); + ten->directdata = lbarray[a]; + ten->name = outliner_idcode_to_plural(GS(id->name)); + } for (id = lbarray[a]->first; id; id = id->next) { - if (id->lib == lib) + if (outliner_library_id_show(lib, id, filter_id_type)) { outliner_add_element(soops, &ten->subtree, id, ten, 0, 0); + } } } } } - } static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) @@ -1292,10 +1335,18 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) TreeElement *ten; ListBase *lbarray[MAX_LIBARRAY]; int a, tot; + short filter_id_type = (soops->filter & SO_FILTER_ID_TYPE) ? soops->filter_id_type : 0; - tot = set_listbasepointers(mainvar, lbarray); + if (filter_id_type) { + lbarray[0] = which_libbase(mainvar, soops->filter_id_type); + tot = 1; + } + else { + tot = set_listbasepointers(mainvar, lbarray); + } + for (a = 0; a < tot; a++) { - if (lbarray[a]->first) { + if (lbarray[a] && lbarray[a]->first) { ID *id = lbarray[a]->first; /* check if there are any datablocks of this type which are orphans */ @@ -1306,21 +1357,19 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) if (id) { /* header for this type of datablock */ - /* TODO's: - * - Add a parameter to BKE_idcode_to_name_plural to get a sane "user-visible" name instead? - * - Ensure that this uses nice icons for the datablock type involved instead of the dot? - */ - ten = outliner_add_element(soops, &soops->tree, lbarray[a], NULL, TSE_ID_BASE, 0); - ten->directdata = lbarray[a]; - - ten->name = BKE_idcode_to_name_plural(GS(id->name)); - if (ten->name == NULL) - ten->name = "UNKNOWN"; + if (filter_id_type) { + ten = NULL; + } + else { + ten = outliner_add_element(soops, &soops->tree, lbarray[a], NULL, TSE_ID_BASE, 0); + ten->directdata = lbarray[a]; + ten->name = outliner_idcode_to_plural(GS(id->name)); + } /* add the orphaned datablocks - these will not be added with any subtrees attached */ for (id = lbarray[a]->first; id; id = id->next) { if (ID_REAL_USERS(id) <= 0) - outliner_add_element(soops, &ten->subtree, id, ten, 0, 0); + outliner_add_element(soops, (ten) ? &ten->subtree : &soops->tree, id, ten, 0, 0); } } } @@ -1412,33 +1461,12 @@ static void outliner_add_layer_collection_objects( } } -static bool outliner_layer_collection_is_visible(LayerCollection *lc) -{ - if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) { - return true; - } - - for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { - if (outliner_layer_collection_is_visible(nlc)) { - return true; - } - } - - return false; -} - static void outliner_add_layer_collections_recursive( SpaceOops *soops, ListBase *tree, ViewLayer *layer, ListBase *layer_collections, TreeElement *parent_ten, const bool show_objects) { for (LayerCollection *lc = layer_collections->first; lc; lc = lc->next) { - if ((soops->outlinevis != SO_VIEW_LAYER) && - !outliner_layer_collection_is_visible(lc)) - { - continue; - } - ID *id = &lc->collection->id; TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0); @@ -1477,7 +1505,7 @@ static void outliner_add_view_layer(SpaceOops *soops, ListBase *tree, TreeElemen BLI_INLINE void outliner_add_collection_init(TreeElement *te, Collection *collection) { if (collection->flag & COLLECTION_IS_MASTER) { - te->name = IFACE_("Collections"); + te->name = IFACE_("Scene Collection"); } else { te->name = collection->id.name + 2; @@ -1776,7 +1804,8 @@ static TreeElement *outliner_find_first_desired_element_at_y( te = outliner_find_item_at_y(soops, &soops->tree, view_co); bool (*callback_test)(TreeElement *); - if (soops->outlinevis == SO_OBJECTS) { + if ((soops->outlinevis == SO_VIEW_LAYER) && + (soops->filter & SO_FILTER_NO_COLLECTION)) { callback_test = test_object_callback; } else { @@ -1855,7 +1884,7 @@ static int outliner_exclude_filter_get(SpaceOops *soops) return (exclude_filter & SO_FILTER_SEARCH); } - if (soops->outlinevis == SO_COLLECTIONS && (soops->filter & SO_FILTER_NO_OBJECT)) { + if (soops->filter & SO_FILTER_NO_OBJECT) { exclude_filter |= SO_FILTER_OB_TYPE; } @@ -2070,7 +2099,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa /* Are we looking for something - we want to tag parents to filter child matches * - NOT in datablocks view - searching all datablocks takes way too long to be useful * - this variable is only set once per tree build */ - if (soops->search_string[0] != 0 && soops->outlinevis != SO_DATABLOCKS) + if (soops->search_string[0] != 0 && soops->outlinevis != SO_DATA_API) soops->search_flags |= SO_SEARCH_RECURSIVE; else soops->search_flags &= ~SO_SEARCH_RECURSIVE; @@ -2177,7 +2206,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa seq = seq->next; } } - else if (soops->outlinevis == SO_DATABLOCKS) { + else if (soops->outlinevis == SO_DATA_API) { PointerRNA mainptr; RNA_main_pointer_create(mainvar, &mainptr); @@ -2192,59 +2221,25 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa else if (soops->outlinevis == SO_ID_ORPHANS) { outliner_add_orphaned_datablocks(mainvar, soops); } - else if (soops->outlinevis == SO_COLLECTIONS && - soops->filter_collection != SO_FILTER_COLLECTION_SCENE) { - Collection *collection; - for (collection = mainvar->collection.first; collection; collection = collection->id.next) { - if (soops->filter_collection == SO_FILTER_COLLECTION_UNLINKED) { - /* Skip collections used in a scene */ - if (BKE_collection_is_in_scene(collection)) { - continue; - } - } - - if (collection->parents.first) { - /* Don't show child collections of non-scene master collection, - * they are already shown as children. */ - bool has_non_scene_parent = false; - - for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) { - if (!(cparent->collection->flag & COLLECTION_IS_MASTER)) { - has_non_scene_parent = true; - } - } - - if (has_non_scene_parent) { - continue; - } + else if (soops->outlinevis == SO_VIEW_LAYER) { + if (soops->filter & SO_FILTER_NO_COLLECTION) { + /* Show objects in the view layer. */ + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + TreeElement *te_object = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + te_object->directdata = base; } - te = outliner_add_element(soops, &soops->tree, collection, NULL, 0, 0); + outliner_make_object_parent_hierarchy(&soops->tree); } - } - else if (ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS)) { - /* Show collections and objects in the view layer. */ - TreeElement *tenlay = outliner_add_element(soops, &soops->tree, scene, te, TSE_R_LAYER, 0); - tenlay->name = view_layer->name; - tenlay->directdata = view_layer; - TREESTORE(tenlay)->flag &= ~TSE_CLOSED; - - bool show_objects = (soops->outlinevis == SO_COLLECTIONS) && - !(soops->filter & SO_FILTER_NO_OBJECT); - outliner_add_view_layer(soops, &tenlay->subtree, tenlay, view_layer, show_objects); - } - else { /* SO_OBJECTS */ - /* Show objects in the view layer. */ - TreeElement *tenlay = outliner_add_element(soops, &soops->tree, scene, te, TSE_R_LAYER, 0); - tenlay->name = view_layer->name; - tenlay->directdata = view_layer; - TREESTORE(tenlay)->flag &= ~TSE_CLOSED; + else { + /* Show collections in the view layer. */ + ten = outliner_add_element(soops, &soops->tree, scene, NULL, TSE_VIEW_COLLECTION_BASE, 0); + ten->name = IFACE_("Scene Collection"); + TREESTORE(ten)->flag &= ~TSE_CLOSED; - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - TreeElement *te_object = outliner_add_element(soops, &tenlay->subtree, base->object, NULL, 0, 0); - te_object->directdata = base; + bool show_objects = !(soops->filter & SO_FILTER_NO_OBJECT); + outliner_add_view_layer(soops, &ten->subtree, ten, view_layer, show_objects); } - outliner_make_object_parent_hierarchy(&tenlay->subtree); } if ((soops->flag & SO_SKIP_SORT_ALPHA) == 0) { diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index dc6406fcc18..72ce24aaff5 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -159,7 +159,7 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent * UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - if (!ELEM(soops->outlinevis, SO_SCENES, SO_COLLECTIONS, SO_OBJECTS)) { + if (!ELEM(soops->outlinevis, SO_VIEW_LAYER)) { return false; } @@ -434,7 +434,7 @@ static void outliner_main_region_message_subscribe( .notify = ED_region_do_msg_notify_tag_redraw, }; - if (ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS, SO_OBJECTS)) { + if (ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_SCENES)) { WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw); } } @@ -483,6 +483,7 @@ static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED( soutliner = MEM_callocN(sizeof(SpaceOops), "initoutliner"); soutliner->spacetype = SPACE_OUTLINER; + soutliner->filter_id_type = ID_GR; /* header */ ar = MEM_callocN(sizeof(ARegion), "header for outliner"); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index ede18b73175..3f795651c65 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1017,7 +1017,7 @@ static void view3d_main_region_listener( static void view3d_main_region_message_subscribe( const struct bContext *C, - struct WorkSpace *workspace, struct Scene *scene, + struct WorkSpace *workspace, struct Scene *UNUSED(scene), struct bScreen *UNUSED(screen), struct ScrArea *UNUSED(sa), struct ARegion *ar, struct wmMsgBus *mbus) { @@ -1075,19 +1075,7 @@ static void view3d_main_region_message_subscribe( WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, use_border, &msg_sub_value_region_tag_redraw); } - /* Each engine could be responsible for its own engine data types. - * For now this is simplest. */ - if (STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE)) { - extern StructRNA RNA_ViewLayerEngineSettingsEevee; - WM_msg_subscribe_rna_anon_type(mbus, ViewLayerEngineSettingsEevee, &msg_sub_value_region_tag_redraw); - } -#ifdef WITH_CLAY_ENGINE - else if (STREQ(scene->r.engine, RE_engine_id_BLENDER_CLAY)) { - extern StructRNA RNA_ViewLayerEngineSettingsClay; - WM_msg_subscribe_rna_anon_type(mbus, ViewLayerEngineSettingsClay, &msg_sub_value_region_tag_redraw); - } -#endif - + WM_msg_subscribe_rna_anon_type(mbus, SceneEEVEE, &msg_sub_value_region_tag_redraw); WM_msg_subscribe_rna_anon_type(mbus, SceneDisplay, &msg_sub_value_region_tag_redraw); WM_msg_subscribe_rna_anon_type(mbus, ObjectDisplay, &msg_sub_value_region_tag_redraw); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index a3990091b12..c479267603d 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -4607,7 +4607,7 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2]) .snap_select = SNAP_ALL, .use_object_edit_cage = false, }, - mval_fl, &dist_px, NULL, + mval_fl, &dist_px, cursor_curr->location, ray_no, NULL, &ob_dummy, obmat)) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 3c026f71769..12229b8c940 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2027,7 +2027,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) if (!(point->flag & PEP_TRANSFORM)) continue; if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + i, mat); for (k = 0, key = point->keys; k < point->totkey; k++, key++) { if (key->flag & PEK_USE_WCO) { @@ -2105,7 +2105,7 @@ void flushTransParticles(TransInfo *t) if (!(point->flag & PEP_TRANSFORM)) continue; if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + i, mat); invert_m4_m4(imat, mat); for (k = 0, key = point->keys; k < point->totkey; k++, key++) { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 681f955087a..948eb47965f 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1195,16 +1195,15 @@ bool snapObjectsTransform( float *dist_px, float r_loc[3], float r_no[3]) { - return ED_transform_snap_object_project_view3d_ex( + return ED_transform_snap_object_project_view3d( t->tsnap.object_context, t->scene->toolsettings->snap_mode, &(const struct SnapObjectParams){ .snap_select = t->tsnap.modeSelect, .use_object_edit_cage = (t->flag & T_EDIT) != 0, + .use_occlusion_test = t->scene->toolsettings->snap_mode != SCE_SNAP_MODE_FACE, }, - mval, dist_px, NULL, - r_loc, r_no, NULL, - NULL, NULL); + mval, dist_px, r_loc, r_no); } diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index eb8fa0480ce..ec3f9793889 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -71,6 +71,8 @@ /** Internal Data Types * \{ */ +#define MAX_CLIPPLANE_LEN 3 + enum eViewProj { VIEW_PROJ_NONE = -1, VIEW_PROJ_ORTHO = 0, @@ -80,12 +82,11 @@ enum eViewProj { typedef struct SnapData { short snap_to; float mval[2]; - float ray_start[3]; - float ray_dir[3]; float pmat[4][4]; /* perspective matrix */ float win_size[2];/* win x and y */ enum eViewProj view_proj; - float depth_range[2]; + float clip_plane[MAX_CLIPPLANE_LEN][4]; + short clip_plane_len; } SnapData; typedef struct SnapObjectData { @@ -196,38 +197,6 @@ static void iter_snap_objects( } -/** - * Generates a struct with the immutable parameters that will be used on all objects. - * - * \param snap_to: Element to snap, Vertice, Edge or Face. - * \param view_proj: ORTHO or PERSP. - * Currently only works one at a time, but can eventually operate as flag. - * - * \param mval: Mouse coords. - * (When NULL, ray-casting is handled without any projection matrix correction.) - * \param ray_origin: ray_start before being moved toward the ray_normal at the distance from vew3d clip_min. - * \param ray_start: ray_origin moved for the start clipping plane (clip_min). - * \param ray_direction: Unit length direction of the ray. - * \param depth_range: distances of clipe plane min and clip plane max; - */ -static void snap_data_set( - SnapData *snapdata, - const ARegion *ar, const unsigned short snap_to, const enum eViewProj view_proj, - const float mval[2], const float ray_start[3], const float ray_direction[3], - const float depth_range[2]) -{ - copy_m4_m4(snapdata->pmat, ((RegionView3D *)ar->regiondata)->persmat); - snapdata->win_size[0] = ar->winx; - snapdata->win_size[1] = ar->winy; - copy_v2_v2(snapdata->mval, mval); - snapdata->snap_to = snap_to; - copy_v3_v3(snapdata->ray_start, ray_start); - copy_v3_v3(snapdata->ray_dir, ray_direction); - snapdata->view_proj = view_proj; - copy_v2_v2(snapdata->depth_range, depth_range); -} - - MINLINE float depth_get(const float co[3], const float ray_start[3], const float ray_dir[3]) { float dvec[3]; @@ -682,7 +651,7 @@ static bool raycastObj( SnapObjectContext *sctx, const float ray_start[3], const float ray_dir[3], Object *ob, float obmat[4][4], const unsigned int ob_index, - bool use_obedit, + bool use_obedit, bool use_occlusion_test, /* read/write args */ float *ray_depth, /* return args */ @@ -692,6 +661,15 @@ static bool raycastObj( { bool retval = false; + if (use_occlusion_test) { + if (use_obedit && sctx->use_v3d && + !(sctx->v3d_data.v3d->flag & V3D_ZBUF_SELECT)) + { + /* Use of occlude geometry in editing mode disabled. */ + return false; + } + } + switch (ob->type) { case OB_MESH: if (use_obedit) { @@ -739,16 +717,19 @@ struct RaycastObjUserData { Object **r_ob; float (*r_obmat)[4]; ListBase *r_hit_list; + bool use_occlusion_test; bool ret; }; static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data) { struct RaycastObjUserData *dt = data; + dt->ret |= raycastObj( sctx, dt->ray_start, dt->ray_dir, - ob, obmat, dt->ob_index++, is_obedit, + ob, obmat, dt->ob_index++, + is_obedit, dt->use_occlusion_test, dt->ray_depth, dt->r_loc, dt->r_no, dt->r_index, dt->r_ob, dt->r_obmat, @@ -805,6 +786,7 @@ static bool raycastObjects( .r_ob = r_ob, .r_obmat = r_obmat, .r_hit_list = r_hit_list, + .use_occlusion_test = params->use_occlusion_test, .ret = false, }; @@ -900,29 +882,26 @@ static void cb_mlooptri_verts_get( } static bool test_projected_vert_dist( - const struct DistProjectedAABBPrecalc *neasrest_precalc, - const float depth_range[2], + const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, const bool is_persp, const float co[3], float *dist_px_sq, float r_co[3]) { - float w; - if (is_persp) { - w = mul_project_m4_v3_zfac(neasrest_precalc->pmat, co); - if (w < depth_range[0] || w > depth_range[1]) { - return false; - } + if (!isect_point_planes_v3_negated(clip_plane, clip_plane_len, co)) { + return false; } float co2d[2] = { - (dot_m4_v3_row_x(neasrest_precalc->pmat, co) + neasrest_precalc->pmat[3][0]), - (dot_m4_v3_row_y(neasrest_precalc->pmat, co) + neasrest_precalc->pmat[3][1]), + (dot_m4_v3_row_x(precalc->pmat, co) + precalc->pmat[3][0]), + (dot_m4_v3_row_y(precalc->pmat, co) + precalc->pmat[3][1]), }; if (is_persp) { + float w = mul_project_m4_v3_zfac(precalc->pmat, co); mul_v2_fl(co2d, 1.0f / w); } - const float dist_sq = len_squared_v2v2(neasrest_precalc->mval, co2d); + const float dist_sq = len_squared_v2v2(precalc->mval, co2d); if (dist_sq < *dist_px_sq) { copy_v3_v3(r_co, co); *dist_px_sq = dist_sq; @@ -932,23 +911,158 @@ static bool test_projected_vert_dist( } static bool test_projected_edge_dist( - const struct DistProjectedAABBPrecalc *neasrest_precalc, - const float depth_range[2], const bool is_persp, - const float va[3], const float vb[3], + const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, + const bool is_persp, const float va[3], const float vb[3], float *dist_px_sq, float r_co[3]) { - - float near_co[3], dummy_depth; - dist_squared_ray_to_seg_v3( - neasrest_precalc->ray_origin, - neasrest_precalc->ray_direction, - va, vb, near_co, &dummy_depth); + float near_co[3], lambda; + if (!isect_ray_seg_v3( + precalc->ray_origin, + precalc->ray_direction, + va, vb, &lambda)) + { + copy_v3_v3(near_co, va); + } + else { + if (lambda <= 0.0f) { + copy_v3_v3(near_co, va); + } + else if (lambda >= 1.0f) { + copy_v3_v3(near_co, vb); + } + else { + interp_v3_v3v3(near_co, va, vb, lambda); + } + } return test_projected_vert_dist( - neasrest_precalc, depth_range, + precalc, clip_plane, clip_plane_len, is_persp, near_co, dist_px_sq, r_co); } +static bool snapMeshPolygon( + SnapObjectContext *sctx, SnapData *snapdata, + Object *ob, float obmat[4][4], + /* read/write args */ + float *dist_px, + /* return args */ + float r_loc[3], float r_no[3], int *r_index) +{ + bool retval = false; + + float lpmat[4][4], dist_px_sq = SQUARE(*dist_px); + mul_m4_m4m4(lpmat, snapdata->pmat, obmat); + + struct DistProjectedAABBPrecalc neasrest_precalc; + dist_squared_to_projected_aabb_precalc( + &neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval); + + float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4]; + transpose_m4_m4(tobmat, obmat); + for (int i = snapdata->clip_plane_len; i--;) { + mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]); + } + + bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; + + SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob); + BLI_assert(sod != NULL); + + if (sod->type == SNAP_MESH) { + Mesh *me = ob->data; + MPoly *mp = &me->mpoly[*r_index]; + + const MLoop *ml = &me->mloop[mp->loopstart]; + for (int i = mp->totloop; i--; ml++) { + if (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) { + const MVert *vert = &me->mvert[ml->v]; + if (test_projected_vert_dist( + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, + is_persp, vert->co, + &dist_px_sq, r_loc)) + { + normal_short_to_float_v3(r_no, vert->no); + *r_index = ml->v; + retval = true; + } + } + else { + float co_pair[2][3]; + const MEdge *edge = &me->medge[ml->e]; + copy_v3_v3(co_pair[0], me->mvert[edge->v1].co); + copy_v3_v3(co_pair[1], me->mvert[edge->v2].co); + if (test_projected_edge_dist( + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, + is_persp, co_pair[0], co_pair[1], + &dist_px_sq, r_loc)) + { + sub_v3_v3v3(r_no, co_pair[0], co_pair[1]); + *r_index = ml->e; + retval = true; + } + } + } + } + else { + BLI_assert(sod->type == SNAP_EDIT_MESH); + + BMEditMesh *em = BKE_editmesh_from_object(ob); + BM_mesh_elem_table_ensure(em->bm, BM_FACE); + BMFace *f = BM_face_at_index(em->bm, *r_index); + + BMLoop *l_iter, *l_first; + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + + do { + if (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) { + const float *co = l_iter->v->co; + if (test_projected_vert_dist( + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, + is_persp, co, + &dist_px_sq, r_loc)) + { + copy_v3_v3(r_no, l_iter->v->no); + *r_index = BM_elem_index_get(l_iter->v); + retval = true; + } + } + else { + float co_pair[2][3]; + copy_v3_v3(co_pair[0], l_iter->e->v1->co); + copy_v3_v3(co_pair[1], l_iter->e->v2->co); + if (test_projected_edge_dist( + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, + is_persp, co_pair[0], co_pair[1], + &dist_px_sq, r_loc)) + { + sub_v3_v3v3(r_no, co_pair[0], co_pair[1]); + *r_index = BM_elem_index_get(l_iter->e); + retval = true; + } + } + } while ((l_iter = l_iter->next) != l_first); + } + + if (retval) { + float imat[4][4]; + invert_m4_m4(imat, obmat); + + mul_m4_v3(obmat, r_loc); + mul_transposed_mat3_m4_v3(obmat, r_no); + normalize_v3(r_no); + + *dist_px = sqrtf(dist_px_sq); + + return true; + } + return false; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -963,7 +1077,6 @@ typedef void (*Nearest2DCopyVertNoCallback)(const int index, float r_no[3], void typedef struct Nearest2dUserData { bool is_persp; - float depth_range[2]; short snap_to; void *userdata; @@ -979,6 +1092,7 @@ typedef struct Nearest2dUserData { static void cb_walk_leaf_snap_vert( void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest) { struct Nearest2dUserData *data = userdata; @@ -988,9 +1102,9 @@ static void cb_walk_leaf_snap_vert( if (test_projected_vert_dist( precalc, - data->depth_range, - data->is_persp, - co, + clip_plane, + clip_plane_len, + data->is_persp, co, &nearest->dist_sq, nearest->co)) { @@ -1002,6 +1116,7 @@ static void cb_walk_leaf_snap_vert( static void cb_walk_leaf_snap_edge( void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest) { struct Nearest2dUserData *data = userdata; @@ -1016,7 +1131,8 @@ static void cb_walk_leaf_snap_edge( if (test_projected_edge_dist( precalc, - data->depth_range, + clip_plane, + clip_plane_len, data->is_persp, v_pair[0], v_pair[1], &nearest->dist_sq, @@ -1031,7 +1147,9 @@ static void cb_walk_leaf_snap_edge( if (vindex[i] == nearest->index) { continue; } - cb_walk_leaf_snap_vert(userdata, vindex[i], precalc, nearest); + cb_walk_leaf_snap_vert( + userdata, vindex[i], precalc, + clip_plane, clip_plane_len, nearest); } } } @@ -1039,6 +1157,7 @@ static void cb_walk_leaf_snap_edge( static void cb_walk_leaf_snap_tri( void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest) { struct Nearest2dUserData *data = userdata; @@ -1051,7 +1170,9 @@ static void cb_walk_leaf_snap_tri( if (eindex[i] == nearest->index) { continue; } - cb_walk_leaf_snap_edge(userdata, eindex[i], precalc, nearest); + cb_walk_leaf_snap_edge( + userdata, eindex[i], precalc, + clip_plane, clip_plane_len, nearest); } } } @@ -1062,7 +1183,9 @@ static void cb_walk_leaf_snap_tri( if (vindex[i] == nearest->index) { continue; } - cb_walk_leaf_snap_vert(userdata, vindex[i], precalc, nearest); + cb_walk_leaf_snap_vert( + userdata, vindex[i], precalc, + clip_plane, clip_plane_len, nearest); } } } @@ -1075,11 +1198,11 @@ static void cb_walk_leaf_snap_tri( static bool snapArmature( SnapData *snapdata, - Object *ob, bArmature *arm, float obmat[4][4], + Object *ob, float obmat[4][4], bool use_obedit, /* read/write args */ - float *ray_depth, float *dist_px, + float *dist_px, /* return args */ - float r_loc[3], float *UNUSED(r_no)) + float r_loc[3], float *UNUSED(r_no), int *r_index) { bool retval = false; @@ -1094,21 +1217,30 @@ static bool snapArmature( dist_squared_to_projected_aabb_precalc( &neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval); - /* Test BoundBox */ - BoundBox *bb = BKE_armature_boundbox_get(ob); - if (bb) { - bool dummy[3]; - /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */ - float bb_dist_px_sq = dist_squared_to_projected_aabb( - &neasrest_precalc, bb->vec[0], bb->vec[6], dummy); - - if (bb_dist_px_sq > dist_px_sq) { - return retval; + if (use_obedit == false) { + /* Test BoundBox */ + BoundBox *bb = BKE_armature_boundbox_get(ob); + if (bb) { + bool dummy[3]; + /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */ + float bb_dist_px_sq = dist_squared_to_projected_aabb( + &neasrest_precalc, bb->vec[0], bb->vec[6], dummy); + + if (bb_dist_px_sq > dist_px_sq) { + return retval; + } } } + float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4]; + transpose_m4_m4(tobmat, obmat); + for (int i = snapdata->clip_plane_len; i--;) { + mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]); + } + bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; + bArmature *arm = ob->data; if (arm->edbo) { for (EditBone *eBone = arm->edbo->first; eBone; eBone = eBone->next) { if (eBone->layer & arm->layer) { @@ -1117,15 +1249,18 @@ static bool snapArmature( switch (snapdata->snap_to) { case SCE_SNAP_MODE_VERTEX: retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, eBone->head, &dist_px_sq, r_loc); retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, eBone->tail, &dist_px_sq, r_loc); break; case SCE_SNAP_MODE_EDGE: retval |= test_projected_edge_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, eBone->head, eBone->tail, &dist_px_sq, r_loc); break; @@ -1145,15 +1280,18 @@ static bool snapArmature( switch (snapdata->snap_to) { case SCE_SNAP_MODE_VERTEX: retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, head_vec, &dist_px_sq, r_loc); retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, tail_vec, &dist_px_sq, r_loc); break; case SCE_SNAP_MODE_EDGE: retval |= test_projected_edge_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, head_vec, tail_vec, &dist_px_sq, r_loc); break; @@ -1164,7 +1302,10 @@ static bool snapArmature( if (retval) { *dist_px = sqrtf(dist_px_sq); mul_m4_v3(obmat, r_loc); - *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir); + if (r_index) { + /* Does not support index. */ + *r_index = -1; + } return true; } return false; @@ -1174,9 +1315,9 @@ static bool snapCurve( SnapData *snapdata, Object *ob, float obmat[4][4], bool use_obedit, /* read/write args */ - float *ray_depth, float *dist_px, + float *dist_px, /* return args */ - float r_loc[3], float *UNUSED(r_no)) + float r_loc[3], float *UNUSED(r_no), int *r_index) { bool retval = false; @@ -1195,83 +1336,93 @@ static bool snapCurve( dist_squared_to_projected_aabb_precalc( &neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval); - /* Test BoundBox */ - BoundBox *bb = BKE_curve_boundbox_get(ob); - if (bb) { - bool dummy[3]; - /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */ - float bb_dist_px_sq = dist_squared_to_projected_aabb( - &neasrest_precalc, bb->vec[0], bb->vec[6], dummy); - - if (bb_dist_px_sq > dist_px_sq) { - return retval; + if (use_obedit == false) { + /* Test BoundBox */ + BoundBox *bb = BKE_curve_boundbox_get(ob); + if (bb) { + bool dummy[3]; + /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */ + float bb_dist_px_sq = dist_squared_to_projected_aabb( + &neasrest_precalc, bb->vec[0], bb->vec[6], dummy); + + if (bb_dist_px_sq > dist_px_sq) { + return retval; + } } } + float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4]; + transpose_m4_m4(tobmat, obmat); + for (int i = snapdata->clip_plane_len; i--;) { + mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]); + } + bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { for (int u = 0; u < nu->pntsu; u++) { - switch (snapdata->snap_to) { - case SCE_SNAP_MODE_VERTEX: - { - if (use_obedit) { + if (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) { + if (use_obedit) { + if (nu->bezt) { + /* don't snap to selected (moving) or hidden */ + if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) { + break; + } + retval |= test_projected_vert_dist( + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, + is_persp, nu->bezt[u].vec[1], &dist_px_sq, + r_loc); + /* don't snap if handle is selected (moving), or if it is aligning to a moving handle */ + if (!(nu->bezt[u].f1 & SELECT) && + !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) + { + retval |= test_projected_vert_dist( + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, + is_persp, nu->bezt[u].vec[0], &dist_px_sq, + r_loc); + } + if (!(nu->bezt[u].f3 & SELECT) && + !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) + { + retval |= test_projected_vert_dist( + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, + is_persp, nu->bezt[u].vec[2], &dist_px_sq, + r_loc); + } + } + else { + /* don't snap to selected (moving) or hidden */ + if (nu->bp[u].f1 & SELECT || nu->bp[u].hide != 0) { + break; + } + retval |= test_projected_vert_dist( + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, + is_persp, nu->bp[u].vec, &dist_px_sq, + r_loc); + } + } + else { + /* curve is not visible outside editmode if nurb length less than two */ + if (nu->pntsu > 1) { if (nu->bezt) { - /* don't snap to selected (moving) or hidden */ - if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) { - break; - } retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, nu->bezt[u].vec[1], &dist_px_sq, r_loc); - /* don't snap if handle is selected (moving), or if it is aligning to a moving handle */ - if (!(nu->bezt[u].f1 & SELECT) && - !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) - { - retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, - is_persp, nu->bezt[u].vec[0], &dist_px_sq, - r_loc); - } - if (!(nu->bezt[u].f3 & SELECT) && - !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) - { - retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, - is_persp, nu->bezt[u].vec[2], &dist_px_sq, - r_loc); - } } else { - /* don't snap to selected (moving) or hidden */ - if (nu->bp[u].f1 & SELECT || nu->bp[u].hide != 0) { - break; - } retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, nu->bp[u].vec, &dist_px_sq, r_loc); } } - else { - /* curve is not visible outside editmode if nurb length less than two */ - if (nu->pntsu > 1) { - if (nu->bezt) { - retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, - is_persp, nu->bezt[u].vec[1], &dist_px_sq, - r_loc); - } - else { - retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, - is_persp, nu->bp[u].vec, &dist_px_sq, - r_loc); - } - } - } - break; } } } @@ -1279,7 +1430,10 @@ static bool snapCurve( if (retval) { *dist_px = sqrtf(dist_px_sq); mul_m4_v3(obmat, r_loc); - *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir); + if (r_index) { + /* Does not support index yet. */ + *r_index = -1; + } return true; } return false; @@ -1290,9 +1444,9 @@ static bool snapEmpty( SnapData *snapdata, Object *ob, float obmat[4][4], /* read/write args */ - float *ray_depth, float *dist_px, + float *dist_px, /* return args */ - float r_loc[3], float *UNUSED(r_no)) + float r_loc[3], float *UNUSED(r_no), int *r_index) { bool retval = false; @@ -1308,32 +1462,46 @@ static bool snapEmpty( dist_squared_to_projected_aabb_precalc( &neasrest_precalc, snapdata->pmat, snapdata->win_size, snapdata->mval); + float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4]; + transpose_m4_m4(tobmat, obmat); + for (int i = snapdata->clip_plane_len; i--;) { + mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]); + } + bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; float dist_px_sq = SQUARE(*dist_px); float co[3]; copy_v3_v3(co, obmat[3]); if (test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, co, &dist_px_sq, r_loc)) { *dist_px = sqrtf(dist_px_sq); - *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir); retval = true; } break; } } - return retval; + if (retval) { + if (r_index) { + /* Does not support index. */ + *r_index = -1; + } + return true; + } + + return false; } static bool snapCamera( const SnapObjectContext *sctx, SnapData *snapdata, Object *object, float obmat[4][4], /* read/write args */ - float *ray_depth, float *dist_px, + float *dist_px, /* return args */ - float r_loc[3], float *UNUSED(r_no)) + float r_loc[3], float *UNUSED(r_no), int *r_index) { Scene *scene = sctx->scene; @@ -1352,6 +1520,12 @@ static bool snapCamera( return retval; } + float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4]; + transpose_m4_m4(tobmat, obmat); + for (int i = snapdata->clip_plane_len; i--;) { + mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]); + } + tracking = &clip->tracking; BKE_tracking_get_camera_object_matrix(scene, object, orig_camera_mat); @@ -1402,7 +1576,8 @@ static bool snapCamera( mul_m4_v3(vertex_obmat, bundle_pos); retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, + clip_planes_local, snapdata->clip_plane_len, is_persp, bundle_pos, &dist_px_sq, r_loc); } } @@ -1413,7 +1588,10 @@ static bool snapCamera( if (retval) { *dist_px = sqrtf(dist_px_sq); - *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir); + if (r_index) { + /* Does not support index. */ + *r_index = -1; + } return true; } return false; @@ -1423,9 +1601,9 @@ static bool snapMesh( SnapObjectContext *sctx, SnapData *snapdata, Object *ob, Mesh *me, float obmat[4][4], /* read/write args */ - float *ray_depth, float *dist_px, + float *dist_px, /* return args */ - float r_loc[3], float r_no[3]) + float r_loc[3], float r_no[3], int *r_index) { bool retval = false; @@ -1553,15 +1731,8 @@ static bool snapMesh( } } - /* Warning: the depth_max is currently being used only in perspective view. - * It is not correct to limit the maximum depth for elements obtained with nearest - * since this limitation depends on the normal and the size of the occlusion face. - * And more... ray_depth is being confused with Z-depth here... (varies only the precision) */ - const float ray_depth_max_global = *ray_depth + snapdata->depth_range[0]; - Nearest2dUserData neasrest2d = { .is_persp = snapdata->view_proj == VIEW_PROJ_PERSP, - .depth_range = {snapdata->depth_range[0], ray_depth_max_global}, .snap_to = snapdata->snap_to, .userdata = treedata, .get_vert_co = (Nearest2DGetVertCoCallback)cb_mvert_co_get, @@ -1576,42 +1747,53 @@ static bool snapMesh( .dist_sq = dist_px_sq, }; + float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4]; + transpose_m4_m4(tobmat, obmat); + for (int i = snapdata->clip_plane_len; i--;) { + mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]); + } + if (bvhtree[1]) { /* snap to loose verts */ BLI_bvhtree_find_nearest_projected( bvhtree[1], lpmat, snapdata->win_size, snapdata->mval, - NULL, 0, &nearest, cb_walk_leaf_snap_vert, &neasrest2d); + clip_planes_local, snapdata->clip_plane_len, + &nearest, cb_walk_leaf_snap_vert, &neasrest2d); } if (bvhtree[0]) { /* snap to loose edges */ BLI_bvhtree_find_nearest_projected( bvhtree[0], lpmat, snapdata->win_size, snapdata->mval, - NULL, 0, &nearest, cb_walk_leaf_snap_edge, &neasrest2d); + clip_planes_local, snapdata->clip_plane_len, + &nearest, cb_walk_leaf_snap_edge, &neasrest2d); } if (treedata->tree) { /* snap to looptris */ BLI_bvhtree_find_nearest_projected( treedata->tree, lpmat, snapdata->win_size, snapdata->mval, - NULL, 0, &nearest, cb_walk_leaf_snap_tri, &neasrest2d); + clip_planes_local, snapdata->clip_plane_len, + &nearest, cb_walk_leaf_snap_tri, &neasrest2d); } if (nearest.index != -1) { - float imat[4][4]; - float timat[3][3]; /* transpose inverse matrix for normals */ - invert_m4_m4(imat, obmat); - transpose_m3_m4(timat, imat); + *dist_px = sqrtf(nearest.dist_sq); copy_v3_v3(r_loc, nearest.co); mul_m4_v3(obmat, r_loc); + if (r_no) { + float imat[4][4]; + invert_m4_m4(imat, obmat); + copy_v3_v3(r_no, nearest.no); - mul_m3_v3(timat, r_no); + mul_transposed_mat3_m4_v3(obmat, r_no); normalize_v3(r_no); } - *dist_px = sqrtf(nearest.dist_sq); - *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir); + if (r_index) { + *r_index = nearest.index; + } retval = true; } @@ -1623,9 +1805,9 @@ static bool snapEditMesh( SnapObjectContext *sctx, SnapData *snapdata, Object *ob, BMEditMesh *em, float obmat[4][4], /* read/write args */ - float *ray_depth, float *dist_px, + float *dist_px, /* return args */ - float r_loc[3], float r_no[3]) + float r_loc[3], float r_no[3], int *r_index) { bool retval = false; @@ -1713,7 +1895,6 @@ static bool snapEditMesh( Nearest2dUserData neasrest2d = { .is_persp = snapdata->view_proj == VIEW_PROJ_PERSP, - .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]}, .snap_to = snapdata->snap_to, .userdata = treedata->em, .get_vert_co = (Nearest2DGetVertCoCallback)cb_bvert_co_get, @@ -1736,27 +1917,35 @@ static bool snapEditMesh( BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT); } - float lpmat[4][4]; + float lpmat[4][4], tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4]; mul_m4_m4m4(lpmat, snapdata->pmat, obmat); + transpose_m4_m4(tobmat, obmat); + + for (int i = snapdata->clip_plane_len; i--;) { + mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]); + } + BLI_bvhtree_find_nearest_projected( treedata->tree, lpmat, snapdata->win_size, snapdata->mval, - NULL, 0, &nearest, cb_walk_leaf, &neasrest2d); + clip_planes_local, snapdata->clip_plane_len, + &nearest, cb_walk_leaf, &neasrest2d); if (nearest.index != -1) { - float imat[4][4]; - float timat[3][3]; /* transpose inverse matrix for normals */ - invert_m4_m4(imat, obmat); - transpose_m3_m4(timat, imat); + *dist_px = sqrtf(nearest.dist_sq); copy_v3_v3(r_loc, nearest.co); mul_m4_v3(obmat, r_loc); if (r_no) { + float imat[4][4]; + invert_m4_m4(imat, obmat); + copy_v3_v3(r_no, nearest.no); - mul_m3_v3(timat, r_no); + mul_transposed_mat3_m4_v3(obmat, r_no); normalize_v3(r_no); } - *dist_px = sqrtf(nearest.dist_sq); - *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir); + if (r_index) { + *r_index = nearest.index; + } retval = true; } @@ -1773,9 +1962,9 @@ static bool snapObject( SnapObjectContext *sctx, SnapData *snapdata, Object *ob, float obmat[4][4], bool use_obedit, /* read/write args */ - float *ray_depth, float *dist_px, + float *dist_px, /* return args */ - float r_loc[3], float r_no[3], + float r_loc[3], float r_no[3], int *r_index, Object **r_ob, float r_obmat[4][4]) { bool retval = false; @@ -1786,45 +1975,45 @@ static bool snapObject( BMEditMesh *em = BKE_editmesh_from_object(ob); retval = snapEditMesh( sctx, snapdata, ob, em, obmat, - ray_depth, dist_px, - r_loc, r_no); + dist_px, + r_loc, r_no, r_index); } else { retval = snapMesh( sctx, snapdata, ob, ob->data, obmat, - ray_depth, dist_px, - r_loc, r_no); + dist_px, + r_loc, r_no, r_index); } break; case OB_ARMATURE: retval = snapArmature( snapdata, - ob, ob->data, obmat, - ray_depth, dist_px, - r_loc, r_no); + ob, obmat, use_obedit, + dist_px, + r_loc, r_no, r_index); break; case OB_CURVE: retval = snapCurve( snapdata, ob, obmat, use_obedit, - ray_depth, dist_px, - r_loc, r_no); + dist_px, + r_loc, r_no, r_index); break; case OB_EMPTY: retval = snapEmpty( snapdata, ob, obmat, - ray_depth, dist_px, - r_loc, r_no); + dist_px, + r_loc, r_no, r_index); break; case OB_CAMERA: retval = snapCamera( sctx, snapdata, ob, obmat, - ray_depth, dist_px, - r_loc, r_no); + dist_px, + r_loc, r_no, r_index); break; } @@ -1845,11 +2034,11 @@ static bool snapObject( struct SnapObjUserData { SnapData *snapdata; /* read/write args */ - float *ray_depth; float *dist_px; /* return args */ float *r_loc; float *r_no; + int *r_index; Object **r_ob; float (*r_obmat)[4]; bool ret; @@ -1862,9 +2051,9 @@ static void sanp_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, flo sctx, dt->snapdata, ob, obmat, is_obedit, /* read/write args */ - dt->ray_depth, dt->dist_px, + dt->dist_px, /* return args */ - dt->r_loc, dt->r_no, + dt->r_loc, dt->r_no, dt->r_index, dt->r_ob, dt->r_obmat); } @@ -1901,18 +2090,18 @@ static bool snapObjectsRay( SnapObjectContext *sctx, SnapData *snapdata, const struct SnapObjectParams *params, /* read/write args */ - float *ray_depth, float *dist_px, + float *dist_px, /* return args */ - float r_loc[3], float r_no[3], + float r_loc[3], float r_no[3], int *r_index, Object **r_ob, float r_obmat[4][4]) { struct SnapObjUserData data = { .snapdata = snapdata, - .ray_depth = ray_depth, .dist_px = dist_px, .r_loc = r_loc, .r_no = r_no, .r_ob = r_ob, + .r_index = r_index, .r_obmat = r_obmat, .ret = false, }; @@ -2111,53 +2300,25 @@ static bool transform_snap_context_project_view3d_mixed_impl( const float mval[2], float *dist_px, float r_co[3], float r_no[3]) { - float ray_depth = BVH_RAYCAST_DIST_MAX; - bool is_hit = false; - const int elem_type[3] = {SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE, SCE_SNAP_MODE_FACE}; BLI_assert(snap_to_flag != 0); BLI_assert((snap_to_flag & ~(1 | 2 | 4)) == 0); - if (params->use_occlusion_test) { - const float dist_px_orig = dist_px ? *dist_px : 0; - for (int i = 2; i >= 0; i--) { - if (snap_to_flag & (1 << i)) { - if (i == 0) { - BLI_assert(dist_px != NULL); - *dist_px = dist_px_orig; - } - if (ED_transform_snap_object_project_view3d( - sctx, - elem_type[i], params, - mval, dist_px, &ray_depth, - r_co, r_no)) - { - /* 0.01 is a random but small value to prioritizing - * the first elements of the loop */ - ray_depth += 0.01f; - is_hit = true; - } - } - } - } - else { - for (int i = 0; i < 3; i++) { - if (snap_to_flag & (1 << i)) { - if (ED_transform_snap_object_project_view3d( - sctx, - elem_type[i], params, - mval, dist_px, &ray_depth, - r_co, r_no)) - { - is_hit = true; - break; - } + for (int i = 0; i < 3; i++) { + if (snap_to_flag & (1 << i)) { + if (ED_transform_snap_object_project_view3d( + sctx, + elem_type[i], params, + mval, dist_px, + r_co, r_no)) + { + return true; } } } - return is_hit; + return false; } /** @@ -2191,55 +2352,98 @@ bool ED_transform_snap_object_project_view3d_ex( const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, - float *ray_depth, float r_loc[3], float r_no[3], int *r_index, Object **r_ob, float r_obmat[4][4]) { - const ARegion *ar = sctx->v3d_data.ar; - const RegionView3D *rv3d = ar->regiondata; + float loc[3], no[3], obmat[4][4]; + Object *ob = NULL; - float ray_origin[3], ray_end[3], ray_start[3], ray_normal[3], depth_range[2]; - - ED_view3d_win_to_origin(ar, mval, ray_origin); - ED_view3d_win_to_vector(ar, mval, ray_normal); + int index_fallback; + if (r_index == NULL) { + r_index = &index_fallback; + } - ED_view3d_clip_range_get( - sctx->depsgraph, - sctx->v3d_data.v3d, sctx->v3d_data.ar->regiondata, - &depth_range[0], &depth_range[1], false); + bool has_hit = false, retval = false; + const ARegion *ar = sctx->v3d_data.ar; + const RegionView3D *rv3d = ar->regiondata; - madd_v3_v3v3fl(ray_start, ray_origin, ray_normal, depth_range[0]); - madd_v3_v3v3fl(ray_end, ray_origin, ray_normal, depth_range[1]); + if (snap_to == SCE_SNAP_MODE_FACE || params->use_occlusion_test) { + float ray_start[3], ray_normal[3]; - if (!ED_view3d_clip_segment(rv3d, ray_start, ray_end)) { - return false; - } + if (!ED_view3d_win_to_ray_ex( + sctx->depsgraph, + sctx->v3d_data.ar, sctx->v3d_data.v3d, + mval, NULL, ray_normal, ray_start, true)) + { + return false; + } - float ray_depth_fallback; - if (ray_depth == NULL) { - ray_depth_fallback = BVH_RAYCAST_DIST_MAX; - ray_depth = &ray_depth_fallback; - } + float dummy_ray_depth = BVH_RAYCAST_DIST_MAX; - if (snap_to == SCE_SNAP_MODE_FACE) { - return raycastObjects( + has_hit = raycastObjects( sctx, params, ray_start, ray_normal, - ray_depth, r_loc, r_no, r_index, r_ob, r_obmat, NULL); + &dummy_ray_depth, loc, no, + r_index, &ob, obmat, NULL); + + retval = has_hit && (snap_to == SCE_SNAP_MODE_FACE); } - else { + + if (ELEM(snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) { SnapData snapdata; - const enum eViewProj view_proj = rv3d->is_persp ? - VIEW_PROJ_PERSP : VIEW_PROJ_ORTHO; - snap_data_set( - &snapdata, ar, snap_to, view_proj, mval, - ray_start, ray_normal, depth_range); + copy_m4_m4(snapdata.pmat, rv3d->persmat); + snapdata.win_size[0] = ar->winx; + snapdata.win_size[1] = ar->winy; + copy_v2_v2(snapdata.mval, mval); + snapdata.snap_to = snap_to; + snapdata.view_proj = rv3d->is_persp ? VIEW_PROJ_PERSP : VIEW_PROJ_ORTHO; + + planes_from_projmat( + snapdata.pmat, + NULL, NULL, NULL, NULL, + snapdata.clip_plane[0], snapdata.clip_plane[1]); + + snapdata.clip_plane_len = 2; + + if (has_hit) { + /* Compute the new clip_pane but do not add it yet. */ + float new_clipplane[4]; + plane_from_point_normal_v3(new_clipplane, loc, no); + + /* Try to snap only to the polygon. */ + retval |= snapMeshPolygon( + sctx, &snapdata, ob, obmat, + dist_px, loc, no, r_index); + + /* Add the new clip plane to the beginning of the list. */ + for (int i = snapdata.clip_plane_len; i != 0; i--) { + copy_v4_v4(snapdata.clip_plane[i], snapdata.clip_plane[i - 1]); + } + copy_v4_v4(snapdata.clip_plane[0], new_clipplane); + snapdata.clip_plane_len++; + } - return snapObjectsRay( + retval |= snapObjectsRay( sctx, &snapdata, params, - ray_depth, dist_px, r_loc, r_no, r_ob, r_obmat); + dist_px, loc, no, r_index, &ob, obmat); + } + + if (retval) { + copy_v3_v3(r_loc, loc); + if (r_no) { + copy_v3_v3(r_no, no); + } + if (r_ob) { + *r_ob = ob; + } + if (r_obmat) { + copy_m4_m4(r_obmat, obmat); + } + return true; } + + return false; } bool ED_transform_snap_object_project_view3d( @@ -2247,7 +2451,6 @@ bool ED_transform_snap_object_project_view3d( const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, - float *ray_depth, float r_loc[3], float r_no[3]) { return ED_transform_snap_object_project_view3d_ex( @@ -2255,7 +2458,6 @@ bool ED_transform_snap_object_project_view3d( snap_to, params, mval, dist_px, - ray_depth, r_loc, r_no, NULL, NULL, NULL); } diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 2a672873d86..baaa23c2398 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -50,6 +50,13 @@ enum { GPU_SHADER_FLAGS_NEW_SHADING = (1 << 1), }; +typedef enum GPUShaderTFBType { + GPU_SHADER_TFB_NONE = 0, /* Transform feedback unsupported. */ + GPU_SHADER_TFB_POINTS = 1, + GPU_SHADER_TFB_LINES = 2, + GPU_SHADER_TFB_TRIANGLES = 3, +} GPUShaderTFBType; + GPUShader *GPU_shader_create( const char *vertexcode, const char *fragcode, @@ -62,12 +69,19 @@ GPUShader *GPU_shader_create_ex( const char *geocode, const char *libcode, const char *defines, - const int flags); + const int flags, + const GPUShaderTFBType tf_type, + const char **tf_names, + const int tf_count); void GPU_shader_free(GPUShader *shader); void GPU_shader_bind(GPUShader *shader); void GPU_shader_unbind(void); +/* Returns true if transform feedback was succesfully enabled. */ +bool GPU_shader_transform_feedback_enable(GPUShader *shader, unsigned int vbo_id); +void GPU_shader_transform_feedback_disable(GPUShader *shader); + int GPU_shader_get_program(GPUShader *shader); void *GPU_shader_get_interface(GPUShader *shader); diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 02baa2e58cb..2068c5a6a75 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -268,7 +268,10 @@ GPUShader *GPU_shader_create(const char *vertexcode, geocode, libcode, defines, - GPU_SHADER_FLAGS_NONE); + GPU_SHADER_FLAGS_NONE, + GPU_SHADER_TFB_NONE, + NULL, + 0); } #define DEBUG_SHADER_NONE "" @@ -323,7 +326,10 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, const char *geocode, const char *libcode, const char *defines, - const int flags) + const int flags, + const GPUShaderTFBType tf_type, + const char **tf_names, + const int tf_count) { #ifdef WITH_OPENSUBDIV bool use_opensubdiv = (flags & GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV) != 0; @@ -469,6 +475,13 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, } #endif + if (tf_names != NULL) { + glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS); + /* Primitive type must be setup */ + BLI_assert(tf_type != GPU_SHADER_TFB_NONE); + shader->feedback_transform_type = tf_type; + } + glLinkProgram(shader->program); glGetProgramiv(shader->program, GL_LINK_STATUS, &status); if (!status) { @@ -527,6 +540,27 @@ void GPU_shader_unbind(void) glUseProgram(0); } +bool GPU_shader_transform_feedback_enable(GPUShader *shader, unsigned int vbo_id) +{ + if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) { + return false; + } + + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id); + + switch (shader->feedback_transform_type) { + case GPU_SHADER_TFB_POINTS: glBeginTransformFeedback(GL_POINTS); return true; + case GPU_SHADER_TFB_LINES: glBeginTransformFeedback(GL_LINES); return true; + case GPU_SHADER_TFB_TRIANGLES: glBeginTransformFeedback(GL_TRIANGLES); return true; + default: return false; + } +} + +void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader)) +{ + glEndTransformFeedback(); +} + void GPU_shader_free(GPUShader *shader) { BLI_assert(shader); diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h index 67d8c6e6213..d8ec6b5d6d1 100644 --- a/source/blender/gpu/intern/gpu_shader_private.h +++ b/source/blender/gpu/intern/gpu_shader_private.h @@ -36,6 +36,8 @@ struct GPUShader { GLuint fragment; /* handle for fragment shader */ Gwn_ShaderInterface *interface; /* cached uniform & attrib interface for shader */ + + int feedback_transform_type; }; #endif /* __GPU_SHADER_PRIVATE_H__ */ diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 45701f090fa..04179787410 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1227,6 +1227,16 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl result.ssr_id = REFRACT_CLOSURE_FLAG; } +void node_ambient_occlusion(vec4 color, vec3 vN, out Closure result) +{ + vec3 bent_normal; + vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0); + float final_ao = occlusion_compute(normalize(worldNormal), viewPosition, 1.0, rand, bent_normal); + result = CLOSURE_DEFAULT; + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.radiance = final_ao * color.rgb; +} + #endif /* VOLUMETRICS */ /* emission */ @@ -2544,4 +2554,28 @@ void node_eevee_specular( result.ssr_id = int(ssr_id); } +void node_shadertorgb(Closure cl, out vec4 outcol, out float outalpha) +{ + vec4 spec_accum = vec4(0.0); + if (ssrToggle && cl.ssr_id == outputSsrId) { + vec3 V = cameraVec; + vec3 vN = normal_decode(cl.ssr_normal, viewCameraVec); + vec3 N = transform_direction(ViewMatrixInverse, vN); + float roughness = cl.ssr_data.a; + float roughnessSquared = max(1e-3, roughness * roughness); + fallback_cubemap(N, V, worldPosition, viewPosition, roughness, roughnessSquared, spec_accum); + } + + outalpha = cl.opacity; + outcol = vec4((spec_accum.rgb * cl.ssr_data.rgb) + cl.radiance, 1.0); + +# ifdef USE_SSS +# ifdef USE_SSS_ALBEDO + outcol += (cl.sss_data * cl.sss_albedo); +# else + outcol += cl.sss_data; +# endif +# endif +} + #endif /* VOLUMETRICS */ diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h index d005c698518..66a8c3e236d 100644 --- a/source/blender/makesdna/DNA_layer_types.h +++ b/source/blender/makesdna/DNA_layer_types.h @@ -70,7 +70,6 @@ typedef struct ViewLayer { struct Base *basact; ListBase layer_collections; /* LayerCollection */ LayerCollection *active_collection; - struct IDProperty *properties_evaluated; /* Old SceneRenderLayer data. */ int layflag; diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 5ce24916c54..4e347cc4363 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -93,6 +93,9 @@ typedef struct MeshRuntime { /** 'BVHCache', for 'BKE_bvhutil.c' */ struct LinkNode *bvh_cache; + + int deformed_only; /* set by modifier stack if only deformed from original */ + char padding[4]; } MeshRuntime; typedef struct Mesh { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 31900b98564..bd337443edc 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -738,8 +738,8 @@ typedef struct ParticleSystemModifierData { ModifierData modifier; struct ParticleSystem *psys; - struct DerivedMesh *dm_final; /* Final DM - its topology may differ from orig mesh. */ - struct DerivedMesh *dm_deformed; /* Deformed-onle DM - its topology is same as orig mesh one. */ + struct Mesh *mesh_final; /* Final Mesh - its topology may differ from orig mesh. */ + struct Mesh *mesh_deformed; /* Deformed-only Mesh - its topology is same as orig mesh one. */ int totdmvert, totdmedge, totdmface; short flag, pad; } ParticleSystemModifierData; diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h index 07d428e0142..d775061d85a 100644 --- a/source/blender/makesdna/DNA_outliner_types.h +++ b/source/blender/makesdna/DNA_outliner_types.h @@ -103,8 +103,8 @@ enum { #define TSE_ID_BASE 36 /* NO ID */ #define TSE_GP_LAYER 37 /* NO ID */ #define TSE_LAYER_COLLECTION 38 -/* #define TSE_COLLECTION 39 */ /* UNUSED */ -#define TSE_SCENE_COLLECTION_BASE 40 +#define TSE_SCENE_COLLECTION_BASE 39 +#define TSE_VIEW_COLLECTION_BASE 40 #define TSE_SCENE_OBJECTS_BASE 41 diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 5c24fd97f57..583b8504524 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -284,7 +284,7 @@ typedef struct ParticleSystem { ListBase pathcachebufs, childcachebufs; /* buffers for the above */ struct ClothModifierData *clmd; /* cloth simulation for hair */ - struct DerivedMesh *hair_in_dm, *hair_out_dm; /* input/output for cloth simulation */ + struct Mesh *hair_in_mesh, *hair_out_mesh; /* input/output for cloth simulation */ struct Object *target_ob; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 98d70e11998..7b717107df1 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1362,8 +1362,68 @@ typedef struct DisplaySafeAreas { typedef struct SceneDisplay { float light_direction[3]; /* light direction for shadows/highlight */ float shadow_shift; + + int matcap_icon; + int matcap_type; + float matcap_rotation; + float matcap_hue; + float matcap_saturation; + float matcap_value; + float matcap_ssao_distance; + float matcap_ssao_attenuation; + float matcap_ssao_factor_cavity; + float matcap_ssao_factor_edge; + float matcap_hair_brightness_randomness; + int matcap_ssao_samples; } SceneDisplay; +typedef struct SceneEEVEE { + int flag; + int gi_diffuse_bounces; + int gi_cubemap_resolution; + int gi_visibility_resolution; + + int taa_samples; + int taa_render_samples; + int sss_samples; + float sss_jitter_threshold; + + float ssr_quality; + float ssr_max_roughness; + float ssr_thickness; + float ssr_border_fade; + float ssr_firefly_fac; + + float volumetric_start; + float volumetric_end; + int volumetric_tile_size; + int volumetric_samples; + float volumetric_sample_distribution; + float volumetric_light_clamp; + int volumetric_shadow_samples; + + float gtao_distance; + float gtao_factor; + float gtao_quality; + + float bokeh_max_size; + float bokeh_threshold; + + float bloom_color[3]; + float bloom_threshold; + float bloom_knee; + float bloom_intensity; + float bloom_radius; + float bloom_clamp; + + int motion_blur_samples; + float motion_blur_shutter; + + int shadow_method; + int shadow_cube_size; + int shadow_cascade_size; +} SceneEEVEE; + /* *************************************************************** */ /* Scene ID-Block */ @@ -1455,10 +1515,10 @@ typedef struct Scene { Collection *master_collection; struct SceneCollection *collection DNA_DEPRECATED; - IDProperty *collection_properties; /* settings to be overriden by layer collections */ IDProperty *layer_properties; /* settings to be override by workspaces */ struct SceneDisplay display; + struct SceneEEVEE eevee; } Scene; /* **************** RENDERDATA ********************* */ @@ -2041,6 +2101,34 @@ typedef enum eGPencil_Placement_Flags { #define USER_UNIT_OPT_SPLIT 1 #define USER_UNIT_ROT_RADIANS 2 +/* SceneEEVEE->flag */ +enum { + SCE_EEVEE_VOLUMETRIC_ENABLED = (1 << 0), + SCE_EEVEE_VOLUMETRIC_LIGHTS = (1 << 1), + SCE_EEVEE_VOLUMETRIC_SHADOWS = (1 << 2), + SCE_EEVEE_VOLUMETRIC_COLORED = (1 << 3), + SCE_EEVEE_GTAO_ENABLED = (1 << 4), + SCE_EEVEE_GTAO_BENT_NORMALS = (1 << 5), + SCE_EEVEE_GTAO_BOUNCE = (1 << 6), + SCE_EEVEE_DOF_ENABLED = (1 << 7), + SCE_EEVEE_BLOOM_ENABLED = (1 << 8), + SCE_EEVEE_MOTION_BLUR_ENABLED = (1 << 9), + SCE_EEVEE_SHADOW_HIGH_BITDEPTH = (1 << 10), + SCE_EEVEE_TAA_REPROJECTION = (1 << 11), + SCE_EEVEE_SSS_ENABLED = (1 << 12), + SCE_EEVEE_SSS_SEPARATE_ALBEDO = (1 << 13), + SCE_EEVEE_SSR_ENABLED = (1 << 14), + SCE_EEVEE_SSR_REFRACTION = (1 << 15), + SCE_EEVEE_SSR_HALF_RESOLUTION = (1 << 16), +}; + +/* SceneEEVEE->shadow_method */ +enum { + SHADOW_ESM = 1, + SHADOW_VSM = 2, + SHADOW_METHOD_MAX = 3, +}; + #ifdef __cplusplus } #endif diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index a079975e754..588d90fae8d 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -253,8 +253,8 @@ typedef struct SpaceOops { short flag, outlinevis, storeflag, search_flags; int filter; char filter_state; - char filter_collection; - char pad[2]; + char pad; + short filter_id_type; /* pointers to treestore elements, grouped by (id, type, nr) in hashtable for faster searching */ void *treehash; @@ -263,11 +263,11 @@ typedef struct SpaceOops { /* SpaceOops->flag */ typedef enum eSpaceOutliner_Flag { - SO_TESTBLOCKS = (1 << 0), - SO_NEWSELECTED = (1 << 1), - SO_HIDE_RESTRICTCOLS = (1 << 2), - SO_HIDE_KEYINGSETINFO = (1 << 3), - SO_SKIP_SORT_ALPHA = (1 << 4), + SO_TESTBLOCKS = (1 << 0), + SO_NEWSELECTED = (1 << 1), + SO_HIDE_RESTRICTCOLS = (1 << 2), + SO_HIDE_KEYINGSETINFO = (1 << 3), + SO_SKIP_SORT_ALPHA = (1 << 4), } eSpaceOutliner_Flag; /* SpaceOops->filter */ @@ -290,6 +290,9 @@ typedef enum eSpaceOutliner_Filter { SO_FILTER_OB_STATE_VISIBLE = (1 << 13), /* Not set via DNA. */ SO_FILTER_OB_STATE_SELECTED = (1 << 14), /* Not set via DNA. */ SO_FILTER_OB_STATE_ACTIVE = (1 << 15), /* Not set via DNA. */ + SO_FILTER_NO_COLLECTION = (1 << 16), + + SO_FILTER_ID_TYPE = (1 << 17), } eSpaceOutliner_Filter; #define SO_FILTER_OB_TYPE (SO_FILTER_NO_OB_MESH | \ @@ -306,7 +309,8 @@ typedef enum eSpaceOutliner_Filter { #define SO_FILTER_ANY (SO_FILTER_NO_OB_CONTENT | \ SO_FILTER_NO_CHILDREN | \ SO_FILTER_OB_TYPE | \ - SO_FILTER_OB_STATE) + SO_FILTER_OB_STATE | \ + SO_FILTER_NO_COLLECTION) /* SpaceOops->filter_state */ typedef enum eSpaceOutliner_StateFilter { @@ -316,12 +320,6 @@ typedef enum eSpaceOutliner_StateFilter { SO_FILTER_OB_ACTIVE = 3, } eSpaceOutliner_StateFilter; -typedef enum eSpaceOutliner_CollectionFilter { - SO_FILTER_COLLECTION_SCENE = 0, - SO_FILTER_COLLECTION_UNLINKED = 1, - SO_FILTER_COLLECTION_ALL = 2, -} eSpaceOutliner_CollectionFilter; - /* SpaceOops->outlinevis */ typedef enum eSpaceOutliner_Mode { SO_SCENES = 0, @@ -330,17 +328,16 @@ typedef enum eSpaceOutliner_Mode { /* SO_SELECTED = 3, */ /* deprecated! */ /* SO_ACTIVE = 4, */ /* deprecated! */ /* SO_SAME_TYPE = 5, */ /* deprecated! */ - SO_OBJECTS = 6, + /* SO_GROUPS = 6, */ /* deprecated! */ SO_LIBRARIES = 7, /* SO_VERSE_SESSION = 8, */ /* deprecated! */ /* SO_VERSE_MS = 9, */ /* deprecated! */ SO_SEQUENCE = 10, - SO_DATABLOCKS = 11, + SO_DATA_API = 11, /* SO_USERDEF = 12, */ /* deprecated! */ /* SO_KEYMAP = 13, */ /* deprecated! */ SO_ID_ORPHANS = 14, - SO_COLLECTIONS = 15, - SO_VIEW_LAYER = 16, + SO_VIEW_LAYER = 15, } eSpaceOutliner_Mode; /* SpaceOops->storeflag */ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 5c54da89f53..0df741df031 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -143,6 +143,9 @@ typedef struct View3DShading { float shadow_intensity; float single_color[3]; + + float studiolight_rot_z; + float pad2; } View3DShading; /* 3D Viewport Overlay setings */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 4d5c591fd17..4744b2e33df 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -503,6 +503,7 @@ extern StructRNA RNA_RigidBodyObject; extern StructRNA RNA_RigidBodyJointConstraint; extern StructRNA RNA_SPHFluidSettings; extern StructRNA RNA_Scene; +extern StructRNA RNA_SceneEEVEE; extern StructRNA RNA_SceneObjects; extern StructRNA RNA_SceneRenderLayer; extern StructRNA RNA_SceneSequence; diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 13067c1ced5..952d27fa18d 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -75,16 +75,15 @@ const EnumPropertyItem rna_enum_id_type_items[] = { {ID_PC, "PAINTCURVE", ICON_CURVE_BEZCURVE, "Paint Curve", ""}, {ID_PAL, "PALETTE", ICON_COLOR, "Palette", ""}, {ID_PA, "PARTICLE", ICON_PARTICLE_DATA, "Particle", ""}, - {ID_LT, "LIGHT_PROBE", ICON_LIGHTPROBE_CUBEMAP, "Light Probe", ""}, + {ID_LP, "LIGHT_PROBE", ICON_LIGHTPROBE_CUBEMAP, "Light Probe", ""}, {ID_SCE, "SCENE", ICON_SCENE_DATA, "Scene", ""}, - {ID_SCR, "SCREEN", ICON_SPLITSCREEN, "Screen", ""}, - {ID_SO, "SOUND", ICON_PLAY_AUDIO, "Sound", ""}, + {ID_SO, "SOUND", ICON_SOUND, "Sound", ""}, {ID_SPK, "SPEAKER", ICON_SPEAKER, "Speaker", ""}, {ID_TXT, "TEXT", ICON_TEXT, "Text", ""}, {ID_TE, "TEXTURE", ICON_TEXTURE_DATA, "Texture", ""}, {ID_WM, "WINDOWMANAGER", ICON_FULLSCREEN, "Window Manager", ""}, {ID_WO, "WORLD", ICON_WORLD_DATA, "World", ""}, - {ID_WS, "WORKSPACE", ICON_NONE, "Workspace", ""}, + {ID_WS, "WORKSPACE", ICON_SPLITSCREEN, "Workspace", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c index 253b0190614..61bf5ceab8e 100644 --- a/source/blender/makesrna/intern/rna_layer.c +++ b/source/blender/makesrna/intern/rna_layer.c @@ -63,314 +63,8 @@ #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_query.h" -/****** layer collection engine settings *******/ - -#define RNA_LAYER_ENGINE_GET_SET(_TYPE_, _ENGINE_, _NAME_) \ -static _TYPE_ rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_get(PointerRNA *ptr) \ -{ \ - IDProperty *props = (IDProperty *)ptr->data; \ - return BKE_collection_engine_property_value_get_##_TYPE_(props, #_NAME_); \ -} \ - \ -static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_set(PointerRNA *ptr, _TYPE_ value) \ -{ \ - IDProperty *props = (IDProperty *)ptr->data; \ - BKE_collection_engine_property_value_set_##_TYPE_(props, #_NAME_, value); \ -} - -#define RNA_LAYER_ENGINE_GET_SET_ARRAY(_TYPE_, _ENGINE_, _NAME_, _LEN_) \ -static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_get(PointerRNA *ptr, _TYPE_ *values) \ -{ \ - IDProperty *props = (IDProperty *)ptr->data; \ - IDProperty *idprop = IDP_GetPropertyFromGroup(props, #_NAME_); \ - if (idprop != NULL) { \ - memcpy(values, IDP_Array(idprop), sizeof(_TYPE_) * idprop->len); \ - } \ -} \ - \ -static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_set(PointerRNA *ptr, const _TYPE_ *values) \ -{ \ - IDProperty *props = (IDProperty *)ptr->data; \ - BKE_collection_engine_property_value_set_##_TYPE_##_array(props, #_NAME_, values); \ -} - -#define RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(_NAME_) \ - RNA_LAYER_ENGINE_GET_SET(float, Clay, _NAME_) - -#define RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT_ARRAY(_NAME_, _LEN_) \ - RNA_LAYER_ENGINE_GET_SET_ARRAY(float, Clay, _NAME_, _LEN_) - -#define RNA_LAYER_ENGINE_CLAY_GET_SET_INT(_NAME_) \ - RNA_LAYER_ENGINE_GET_SET(int, Clay, _NAME_) - -#define RNA_LAYER_ENGINE_CLAY_GET_SET_BOOL(_NAME_) \ - RNA_LAYER_ENGINE_GET_SET(bool, Clay, _NAME_) - -#define RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(_NAME_) \ - RNA_LAYER_ENGINE_GET_SET(float, Eevee, _NAME_) - -#define RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT_ARRAY(_NAME_, _LEN_) \ - RNA_LAYER_ENGINE_GET_SET_ARRAY(float, Eevee, _NAME_, _LEN_) - -#define RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(_NAME_) \ - RNA_LAYER_ENGINE_GET_SET(int, Eevee, _NAME_) - -#define RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(_NAME_) \ - RNA_LAYER_ENGINE_GET_SET(bool, Eevee, _NAME_) - -/* clay engine */ -#ifdef WITH_CLAY_ENGINE -/* ViewLayer settings. */ -RNA_LAYER_ENGINE_CLAY_GET_SET_INT(ssao_samples) - -/* LayerCollection settings. */ -RNA_LAYER_ENGINE_CLAY_GET_SET_INT(matcap_icon) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(matcap_rotation) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(matcap_hue) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(matcap_saturation) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(matcap_value) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(ssao_factor_cavity) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(ssao_factor_edge) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(ssao_distance) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(ssao_attenuation) -RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(hair_brightness_randomness) -#endif /* WITH_CLAY_ENGINE */ - -/* eevee engine */ -/* ViewLayer settings. */ -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(gtao_enable) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(gtao_use_bent_normals) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(gtao_bounce) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(gtao_factor) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(gtao_quality) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(gtao_distance) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(dof_enable) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bokeh_max_size) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bokeh_threshold) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(bloom_enable) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_threshold) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT_ARRAY(bloom_color, 3) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_knee) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_radius) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_clamp) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_intensity) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(motion_blur_enable) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(motion_blur_samples) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(motion_blur_shutter) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_enable) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(volumetric_start) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(volumetric_end) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(volumetric_tile_size) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(volumetric_samples) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(volumetric_sample_distribution) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_lights) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(volumetric_light_clamp) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_shadows) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(volumetric_shadow_samples) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_colored_transmittance) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(sss_enable) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(sss_samples) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(sss_jitter_threshold) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(sss_separate_albedo) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_refraction) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_enable) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_halfres) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_quality) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_max_roughness) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_thickness) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_border_fade) -RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_firefly_fac) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(shadow_method) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(shadow_cube_size) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(shadow_cascade_size) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(shadow_high_bitdepth) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(taa_samples) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(taa_render_samples) -RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(taa_reprojection) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(gi_diffuse_bounces) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(gi_cubemap_resolution) -RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(gi_visibility_resolution) - -#undef RNA_LAYER_ENGINE_GET_SET - -static void rna_ViewLayerEngineSettings_update(bContext *C, PointerRNA *UNUSED(ptr)) -{ - Scene *scene = CTX_data_scene(C); - /* TODO(sergey): Use proper flag for tagging here. */ - DEG_id_tag_update(&scene->id, 0); -} - -static void rna_LayerCollectionEngineSettings_update(bContext *UNUSED(C), PointerRNA *ptr) -{ - ID *id = ptr->id.data; - /* TODO(sergey): Use proper flag for tagging here. */ - DEG_id_tag_update(id, 0); - - /* Instead of passing 'noteflag' to the rna update function, we handle the notifier ourselves. - * We need to do this because the LayerCollection may be coming from different ID types (Scene or Collection) - * and when using NC_SCENE the id most match the active scene for the listener to receive the notification.*/ - - WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL); -} - /***********************************/ -static void engine_settings_use(IDProperty *root, IDProperty *props, PointerRNA *props_ptr, const char *identifier) -{ - PropertyRNA *prop = RNA_struct_find_property(props_ptr, identifier); - - switch (RNA_property_type(prop)) { - case PROP_FLOAT: - { - float value = BKE_collection_engine_property_value_get_float(props, identifier); - BKE_collection_engine_property_add_float(root, identifier, value); - break; - } - case PROP_ENUM: - { - int value = BKE_collection_engine_property_value_get_int(props, identifier); - BKE_collection_engine_property_add_int(root, identifier, value); - break; - } - case PROP_INT: - { - int value = BKE_collection_engine_property_value_get_int(props, identifier); - BKE_collection_engine_property_add_int(root, identifier, value); - break; - } - case PROP_BOOLEAN: - { - int value = BKE_collection_engine_property_value_get_int(props, identifier); - BKE_collection_engine_property_add_bool(root, identifier, value); - break; - } - case PROP_STRING: - case PROP_POINTER: - case PROP_COLLECTION: - default: - break; - } -} - -static StructRNA *rna_ViewLayerSettings_refine(PointerRNA *ptr) -{ - IDProperty *props = (IDProperty *)ptr->data; - BLI_assert(props && props->type == IDP_GROUP); - - switch (props->subtype) { - case IDP_GROUP_SUB_ENGINE_RENDER: -#ifdef WITH_CLAY_ENGINE - if (STREQ(props->name, RE_engine_id_BLENDER_CLAY)) { - return &RNA_ViewLayerEngineSettingsClay; - } -#endif - if (STREQ(props->name, RE_engine_id_BLENDER_EEVEE)) { - return &RNA_ViewLayerEngineSettingsEevee; - } - break; - default: - BLI_assert(!"Mode not fully implemented"); - break; - } - - return &RNA_ViewLayerSettings; -} - -static void rna_ViewLayerSettings_name_get(PointerRNA *ptr, char *value) -{ - IDProperty *props = (IDProperty *)ptr->data; - strcpy(value, props->name); -} - -static int rna_ViewLayerSettings_name_length(PointerRNA *ptr) -{ - IDProperty *props = (IDProperty *)ptr->data; - return strnlen(props->name, sizeof(props->name)); -} - -static void rna_ViewLayerSettings_use(ID *id, IDProperty *props, const char *identifier) -{ - Scene *scene = (Scene *)id; - PointerRNA scene_props_ptr; - IDProperty *scene_props; - - scene_props = BKE_view_layer_engine_scene_get(scene, props->name); - RNA_pointer_create(id, &RNA_ViewLayerSettings, scene_props, &scene_props_ptr); - - engine_settings_use(props, scene_props, &scene_props_ptr, identifier); - - /* TODO(sergey): Use proper flag for tagging here. */ - DEG_id_tag_update(id, 0); -} - -static void rna_ViewLayerSettings_unuse(ID *id, IDProperty *props, const char *identifier) -{ - IDProperty *prop_to_remove = IDP_GetPropertyFromGroup(props, identifier); - IDP_FreeFromGroup(props, prop_to_remove); - - /* TODO(sergey): Use proper flag for tagging here. */ - DEG_id_tag_update(id, 0); -} - -static StructRNA *rna_LayerCollectionSettings_refine(PointerRNA *ptr) -{ - IDProperty *props = (IDProperty *)ptr->data; - BLI_assert(props && props->type == IDP_GROUP); - - switch (props->subtype) { - case IDP_GROUP_SUB_ENGINE_RENDER: -#ifdef WITH_CLAY_ENGINE - if (STREQ(props->name, RE_engine_id_BLENDER_CLAY)) { - return &RNA_LayerCollectionEngineSettingsClay; - } -#endif - if (STREQ(props->name, RE_engine_id_BLENDER_EEVEE)) { - /* printf("Mode not fully implemented\n"); */ - return &RNA_LayerCollectionSettings; - } - break; - default: - BLI_assert(!"Mode not fully implemented"); - break; - } - - return &RNA_LayerCollectionSettings; -} - -static void rna_LayerCollectionSettings_name_get(PointerRNA *ptr, char *value) -{ - IDProperty *props = (IDProperty *)ptr->data; - strcpy(value, props->name); -} - -static int rna_LayerCollectionSettings_name_length(PointerRNA *ptr) -{ - IDProperty *props = (IDProperty *)ptr->data; - return strnlen(props->name, sizeof(props->name)); -} - -static void rna_LayerCollectionSettings_use(ID *id, IDProperty *props, const char *identifier) -{ - Scene *scene = (Scene *)id; - PointerRNA scene_props_ptr; - IDProperty *scene_props; - - scene_props = BKE_layer_collection_engine_scene_get(scene, props->name); - RNA_pointer_create(id, &RNA_LayerCollectionSettings, scene_props, &scene_props_ptr); - engine_settings_use(props, scene_props, &scene_props_ptr, identifier); - - /* TODO(sergey): Use proper flag for tagging here. */ - DEG_id_tag_update(id, 0); -} - -static void rna_LayerCollectionSettings_unuse(ID *id, IDProperty *props, const char *identifier) -{ - IDProperty *prop_to_remove = IDP_GetPropertyFromGroup(props, identifier); - IDP_FreeFromGroup(props, prop_to_remove); - - /* TODO(sergey): Use proper flag for tagging here. */ - DEG_id_tag_update(id, 0); -} static PointerRNA rna_LayerCollections_active_collection_get(PointerRNA *ptr) { @@ -384,7 +78,7 @@ static void rna_LayerCollections_active_collection_set(PointerRNA *ptr, PointerR ViewLayer *view_layer = (ViewLayer *)ptr->data; LayerCollection *lc = (LayerCollection *)value.data; const int index = BKE_layer_collection_findindex(view_layer, lc); - if (index != -1) view_layer->active_collection = lc; + if (index != -1) BKE_layer_collection_activate(view_layer, lc); } static PointerRNA rna_LayerObjects_active_object_get(PointerRNA *ptr) @@ -510,694 +204,6 @@ static void rna_LayerCollection_use_update(Main *bmain, Scene *UNUSED(scene), Po #else -#ifdef WITH_CLAY_ENGINE -static void rna_def_view_layer_engine_settings_clay(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "ViewLayerEngineSettingsClay", "ViewLayerSettings"); - RNA_def_struct_ui_text(srna, "Clay Scene Layer Settings", "Clay Engine settings"); - - RNA_define_verify_sdna(0); /* not in sdna */ - - /* see RNA_LAYER_ENGINE_GET_SET macro */ - prop = RNA_def_property(srna, "ssao_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_samples_get", - "rna_LayerEngineSettings_Clay_ssao_samples_set", NULL); - RNA_def_property_ui_text(prop, "Samples", "Number of samples"); - RNA_def_property_range(prop, 1, 500); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - RNA_define_verify_sdna(1); /* not in sdna */ -} -#endif /* WITH_CLAY_ENGINE */ - -static void rna_def_view_layer_engine_settings_eevee(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - /* Keep in sync with eevee_private.h */ - static const EnumPropertyItem eevee_shadow_method_items[] = { - {1, "ESM", 0, "ESM", "Exponential Shadow Mapping"}, - {2, "VSM", 0, "VSM", "Variance Shadow Mapping"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem eevee_shadow_size_items[] = { - {64, "64", 0, "64px", ""}, - {128, "128", 0, "128px", ""}, - {256, "256", 0, "256px", ""}, - {512, "512", 0, "512px", ""}, - {1024, "1024", 0, "1024px", ""}, - {2048, "2048", 0, "2048px", ""}, - {4096, "4096", 0, "4096px", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem eevee_gi_visibility_size_items[] = { - {8, "8", 0, "8px", ""}, - {16, "16", 0, "16px", ""}, - {32, "32", 0, "32px", ""}, - {64, "64", 0, "64px", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem eevee_volumetric_tile_size_items[] = { - {2, "2", 0, "2px", ""}, - {4, "4", 0, "4px", ""}, - {8, "8", 0, "8px", ""}, - {16, "16", 0, "16px", ""}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "ViewLayerEngineSettingsEevee", "ViewLayerSettings"); - RNA_def_struct_ui_text(srna, "Eevee Scene Layer Settings", "Eevee Engine settings"); - - RNA_define_verify_sdna(0); /* not in sdna */ - - /* see RNA_LAYER_ENGINE_GET_SET macro */ - - /* Indirect Lighting */ - prop = RNA_def_property(srna, "gi_diffuse_bounces", PROP_INT, PROP_NONE); - RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_gi_diffuse_bounces_get", - "rna_LayerEngineSettings_Eevee_gi_diffuse_bounces_set", NULL); - RNA_def_property_ui_text(prop, "Diffuse Bounces", "Number of time the light is reinjected inside light grids, " - "0 disable indirect diffuse light"); - RNA_def_property_range(prop, 0, INT_MAX); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "gi_cubemap_resolution", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_funcs(prop, "rna_LayerEngineSettings_Eevee_gi_cubemap_resolution_get", - "rna_LayerEngineSettings_Eevee_gi_cubemap_resolution_set", NULL); - RNA_def_property_enum_items(prop, eevee_shadow_size_items); - RNA_def_property_ui_text(prop, "Cubemap Size", "Size of every cubemaps"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "gi_visibility_resolution", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_funcs(prop, "rna_LayerEngineSettings_Eevee_gi_visibility_resolution_get", - "rna_LayerEngineSettings_Eevee_gi_visibility_resolution_set", NULL); - RNA_def_property_enum_items(prop, eevee_gi_visibility_size_items); - RNA_def_property_ui_text(prop, "Irradiance Visibility Size", - "Size of the shadow map applied to each irradiance sample"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - /* Temporal Anti-Aliasing (super sampling) */ - prop = RNA_def_property(srna, "taa_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_taa_samples_get", - "rna_LayerEngineSettings_Eevee_taa_samples_set", NULL); - RNA_def_property_ui_text(prop, "Viewport Samples", "Number of samples, unlimited if 0"); - RNA_def_property_range(prop, 0, INT_MAX); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "taa_render_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_taa_render_samples_get", - "rna_LayerEngineSettings_Eevee_taa_render_samples_set", NULL); - RNA_def_property_ui_text(prop, "Render Samples", "Number of samples per pixels for rendering"); - RNA_def_property_range(prop, 1, INT_MAX); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "taa_reprojection", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_taa_reprojection_get", - "rna_LayerEngineSettings_Eevee_taa_reprojection_set"); - RNA_def_property_ui_text(prop, "Viewport Denoising", "Denoise image using temporal reprojection " - "(can leave some ghosting)"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - /* Screen Space Subsurface Scattering */ - prop = RNA_def_property(srna, "sss_enable", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_sss_enable_get", - "rna_LayerEngineSettings_Eevee_sss_enable_set"); - RNA_def_property_ui_text(prop, "Subsurface Scattering", "Enable screen space subsurface scattering"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "sss_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_sss_samples_get", - "rna_LayerEngineSettings_Eevee_sss_samples_set", NULL); - RNA_def_property_ui_text(prop, "Samples", "Number of samples to compute the scattering effect"); - RNA_def_property_range(prop, 1, 32); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "sss_jitter_threshold", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_sss_jitter_threshold_get", - "rna_LayerEngineSettings_Eevee_sss_jitter_threshold_set", NULL); - RNA_def_property_ui_text(prop, "Jitter Threshold", "Rotate samples that are below this threshold"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "sss_separate_albedo", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_sss_separate_albedo_get", - "rna_LayerEngineSettings_Eevee_sss_separate_albedo_set"); - RNA_def_property_ui_text(prop, "Separate Albedo", "Avoid albedo being blured by the subsurface scattering " - "but uses more video memory"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - /* Screen Space Reflection */ - prop = RNA_def_property(srna, "ssr_enable", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_enable_get", - "rna_LayerEngineSettings_Eevee_ssr_enable_set"); - RNA_def_property_ui_text(prop, "Screen Space Reflections", "Enable screen space reflection"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "ssr_refraction", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_refraction_get", - "rna_LayerEngineSettings_Eevee_ssr_refraction_set"); - RNA_def_property_ui_text(prop, "Screen Space Refractions", "Enable screen space Refractions"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "ssr_halfres", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_halfres_get", - "rna_LayerEngineSettings_Eevee_ssr_halfres_set"); - RNA_def_property_ui_text(prop, "Half Res Trace", "Raytrace at a lower resolution"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "ssr_quality", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_quality_get", - "rna_LayerEngineSettings_Eevee_ssr_quality_set", NULL); - RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the screen space raytracing"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "ssr_max_roughness", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_max_roughness_get", - "rna_LayerEngineSettings_Eevee_ssr_max_roughness_set", NULL); - RNA_def_property_ui_text(prop, "Max Roughness", "Do not raytrace reflections for roughness above this value"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "ssr_thickness", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_thickness_get", - "rna_LayerEngineSettings_Eevee_ssr_thickness_set", NULL); - RNA_def_property_ui_text(prop, "Thickness", "Pixel thickness used to detect intersection"); - RNA_def_property_range(prop, 1e-6f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 5, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "ssr_border_fade", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_border_fade_get", - "rna_LayerEngineSettings_Eevee_ssr_border_fade_set", NULL); - RNA_def_property_ui_text(prop, "Edge Fading", "Screen percentage used to fade the SSR"); - RNA_def_property_range(prop, 0.0f, 0.5f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "ssr_firefly_fac", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_firefly_fac_get", - "rna_LayerEngineSettings_Eevee_ssr_firefly_fac_set", NULL); - RNA_def_property_ui_text(prop, "Clamp", "Clamp pixel intensity to remove noise (0 to disabled)"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - /* Volumetrics */ - prop = RNA_def_property(srna, "volumetric_enable", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_enable_get", - "rna_LayerEngineSettings_Eevee_volumetric_enable_set"); - RNA_def_property_ui_text(prop, "Volumetrics", "Enable scattering and absorbance of volumetric material"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_start", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_start_get", - "rna_LayerEngineSettings_Eevee_volumetric_start_set", NULL); - RNA_def_property_ui_text(prop, "Start", "Start distance of the volumetric effect"); - RNA_def_property_range(prop, 1e-6f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_end", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_end_get", - "rna_LayerEngineSettings_Eevee_volumetric_end_set", NULL); - RNA_def_property_ui_text(prop, "End", "End distance of the volumetric effect"); - RNA_def_property_range(prop, 1e-6f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_tile_size", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_tile_size_get", - "rna_LayerEngineSettings_Eevee_volumetric_tile_size_set", NULL); - RNA_def_property_enum_items(prop, eevee_volumetric_tile_size_items); - RNA_def_property_ui_text(prop, "Tile Size", "Control the quality of the volumetric effects " - "(lower size increase vram usage and quality)"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_samples_get", - "rna_LayerEngineSettings_Eevee_volumetric_samples_set", NULL); - RNA_def_property_ui_text(prop, "Samples", "Number of samples to compute volumetric effects"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_range(prop, 1, 256); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_sample_distribution", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_sample_distribution_get", - "rna_LayerEngineSettings_Eevee_volumetric_sample_distribution_set", NULL); - RNA_def_property_ui_text(prop, "Exponential Sampling", "Distribute more samples closer to the camera"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_lights", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_lights_get", - "rna_LayerEngineSettings_Eevee_volumetric_lights_set"); - RNA_def_property_ui_text(prop, "Volumetric Lighting", "Enable scene lamps interactions with volumetrics"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_light_clamp", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_light_clamp_get", - "rna_LayerEngineSettings_Eevee_volumetric_light_clamp_set", NULL); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_text(prop, "Clamp", "Maximum light contribution, reducing noise"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_shadows", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_shadows_get", - "rna_LayerEngineSettings_Eevee_volumetric_shadows_set"); - RNA_def_property_ui_text(prop, "Volumetric Shadows", "Generate shadows from volumetric material (Very expensive)"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_shadow_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_shadow_samples_get", - "rna_LayerEngineSettings_Eevee_volumetric_shadow_samples_set", NULL); - RNA_def_property_range(prop, 1, 128); - RNA_def_property_ui_text(prop, "Volumetric Shadow Samples", "Number of samples to compute volumetric shadowing"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "volumetric_colored_transmittance", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_colored_transmittance_get", - "rna_LayerEngineSettings_Eevee_volumetric_colored_transmittance_set"); - RNA_def_property_ui_text(prop, "Colored Transmittance", "Enable wavelength dependent volumetric transmittance"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - /* Ambient Occlusion */ - prop = RNA_def_property(srna, "gtao_enable", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_enable_get", - "rna_LayerEngineSettings_Eevee_gtao_enable_set"); - RNA_def_property_ui_text(prop, "Ambient Occlusion", "Enable ambient occlusion to simulate medium scale indirect shadowing"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "gtao_use_bent_normals", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_use_bent_normals_get", - "rna_LayerEngineSettings_Eevee_gtao_use_bent_normals_set"); - RNA_def_property_ui_text(prop, "Bent Normals", "Compute main non occluded direction to sample the environment"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "gtao_bounce", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_bounce_get", - "rna_LayerEngineSettings_Eevee_gtao_bounce_set"); - RNA_def_property_ui_text(prop, "Bounces Approximation", "An approximation to simulate light bounces " - "giving less occlusion on brighter objects"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "gtao_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_factor_get", "rna_LayerEngineSettings_Eevee_gtao_factor_set", NULL); - RNA_def_property_ui_text(prop, "Factor", "Factor for ambient occlusion blending"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 2); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "gtao_quality", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_quality_get", "rna_LayerEngineSettings_Eevee_gtao_quality_set", NULL); - RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the horizon search"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "gtao_distance", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_distance_get", "rna_LayerEngineSettings_Eevee_gtao_distance_set", NULL); - RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the ambient occlusion effect"); - RNA_def_property_range(prop, 0.0f, 100000.0f); - RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - /* Depth of Field */ - prop = RNA_def_property(srna, "dof_enable", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_dof_enable_get", - "rna_LayerEngineSettings_Eevee_dof_enable_set"); - RNA_def_property_ui_text(prop, "Depth of Field", "Enable depth of field using the values from the active camera"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "bokeh_max_size", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bokeh_max_size_get", - "rna_LayerEngineSettings_Eevee_bokeh_max_size_set", NULL); - RNA_def_property_ui_text(prop, "Max Size", "Max size of the bokeh shape for the depth of field (lower is faster)"); - RNA_def_property_range(prop, 0.0f, 2000.0f); - RNA_def_property_ui_range(prop, 2.0f, 200.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "bokeh_threshold", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bokeh_threshold_get", - "rna_LayerEngineSettings_Eevee_bokeh_threshold_set", NULL); - RNA_def_property_ui_text(prop, "Sprite Threshold", "Brightness threshold for using sprite base depth of field"); - RNA_def_property_range(prop, 0.0f, 100000.0f); - RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - /* Bloom */ - prop = RNA_def_property(srna, "bloom_enable", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_enable_get", - "rna_LayerEngineSettings_Eevee_bloom_enable_set"); - RNA_def_property_ui_text(prop, "Bloom", "High brighness pixels generate a glowing effect"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "bloom_threshold", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_threshold_get", - "rna_LayerEngineSettings_Eevee_bloom_threshold_set", NULL); - RNA_def_property_ui_text(prop, "Threshold", "Filters out pixels under this level of brightness"); - RNA_def_property_range(prop, 0.0f, 100000.0f); - RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "bloom_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 3); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_color_get", - "rna_LayerEngineSettings_Eevee_bloom_color_set", NULL); - RNA_def_property_ui_text(prop, "Color", "Color applied to the bloom effect"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "bloom_knee", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_knee_get", - "rna_LayerEngineSettings_Eevee_bloom_knee_set", NULL); - RNA_def_property_ui_text(prop, "Knee", "Makes transition between under/over-threshold gradual"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "bloom_radius", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_radius_get", - "rna_LayerEngineSettings_Eevee_bloom_radius_set", NULL); - RNA_def_property_ui_text(prop, "Radius", "Bloom spread distance"); - RNA_def_property_range(prop, 0.0f, 100.0f); - RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "bloom_clamp", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_clamp_get", - "rna_LayerEngineSettings_Eevee_bloom_clamp_set", NULL); - RNA_def_property_ui_text(prop, "Clamp", "Maximum intensity a bloom pixel can have"); - RNA_def_property_range(prop, 0.0f, 1000.0f); - RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "bloom_intensity", PROP_FLOAT, PROP_UNSIGNED); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_intensity_get", - "rna_LayerEngineSettings_Eevee_bloom_intensity_set", NULL); - RNA_def_property_ui_text(prop, "Intensity", "Blend factor"); - RNA_def_property_range(prop, 0.0f, 10000.0f); - RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - /* Motion blur */ - prop = RNA_def_property(srna, "motion_blur_enable", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_motion_blur_enable_get", - "rna_LayerEngineSettings_Eevee_motion_blur_enable_set"); - RNA_def_property_ui_text(prop, "Motion Blur", "Enable motion blur effect (only in camera view)"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_motion_blur_samples_get", - "rna_LayerEngineSettings_Eevee_motion_blur_samples_set", NULL); - RNA_def_property_ui_text(prop, "Samples", "Number of samples to take with motion blur"); - RNA_def_property_range(prop, 1, 64); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_motion_blur_shutter_get", - "rna_LayerEngineSettings_Eevee_motion_blur_shutter_set", NULL); - RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close"); - RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 2); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - /* Shadows */ - prop = RNA_def_property(srna, "shadow_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_funcs(prop, "rna_LayerEngineSettings_Eevee_shadow_method_get", "rna_LayerEngineSettings_Eevee_shadow_method_set", NULL); - RNA_def_property_enum_items(prop, eevee_shadow_method_items); - RNA_def_property_ui_text(prop, "Method", "Technique use to compute the shadows"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "shadow_cube_size", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_funcs(prop, "rna_LayerEngineSettings_Eevee_shadow_cube_size_get", "rna_LayerEngineSettings_Eevee_shadow_cube_size_set", NULL); - RNA_def_property_enum_items(prop, eevee_shadow_size_items); - RNA_def_property_ui_text(prop, "Cube Shadows Resolution", "Size of point and area lamps shadow maps"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "shadow_cascade_size", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_funcs(prop, "rna_LayerEngineSettings_Eevee_shadow_cascade_size_get", "rna_LayerEngineSettings_Eevee_shadow_cascade_size_set", NULL); - RNA_def_property_enum_items(prop, eevee_shadow_size_items); - RNA_def_property_ui_text(prop, "Directional Shadows Resolution", "Size of sun lamps shadow maps"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - prop = RNA_def_property(srna, "shadow_high_bitdepth", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_shadow_high_bitdepth_get", "rna_LayerEngineSettings_Eevee_shadow_high_bitdepth_set"); - RNA_def_property_ui_text(prop, "High Bitdepth", "Use 32bit shadows"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update"); - - RNA_define_verify_sdna(1); /* not in sdna */ -} - -#ifdef WITH_CLAY_ENGINE -static void rna_def_layer_collection_engine_settings_clay(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem clay_matcap_items[] = { - {ICON_MATCAP_01, "01", ICON_MATCAP_01, "", ""}, - {ICON_MATCAP_02, "02", ICON_MATCAP_02, "", ""}, - {ICON_MATCAP_03, "03", ICON_MATCAP_03, "", ""}, - {ICON_MATCAP_04, "04", ICON_MATCAP_04, "", ""}, - {ICON_MATCAP_05, "05", ICON_MATCAP_05, "", ""}, - {ICON_MATCAP_06, "06", ICON_MATCAP_06, "", ""}, - {ICON_MATCAP_07, "07", ICON_MATCAP_07, "", ""}, - {ICON_MATCAP_08, "08", ICON_MATCAP_08, "", ""}, - {ICON_MATCAP_09, "09", ICON_MATCAP_09, "", ""}, - {ICON_MATCAP_10, "10", ICON_MATCAP_10, "", ""}, - {ICON_MATCAP_11, "11", ICON_MATCAP_11, "", ""}, - {ICON_MATCAP_12, "12", ICON_MATCAP_12, "", ""}, - {ICON_MATCAP_13, "13", ICON_MATCAP_13, "", ""}, - {ICON_MATCAP_14, "14", ICON_MATCAP_14, "", ""}, - {ICON_MATCAP_15, "15", ICON_MATCAP_15, "", ""}, - {ICON_MATCAP_16, "16", ICON_MATCAP_16, "", ""}, - {ICON_MATCAP_17, "17", ICON_MATCAP_17, "", ""}, - {ICON_MATCAP_18, "18", ICON_MATCAP_18, "", ""}, - {ICON_MATCAP_19, "19", ICON_MATCAP_19, "", ""}, - {ICON_MATCAP_20, "20", ICON_MATCAP_20, "", ""}, - {ICON_MATCAP_21, "21", ICON_MATCAP_21, "", ""}, - {ICON_MATCAP_22, "22", ICON_MATCAP_22, "", ""}, - {ICON_MATCAP_23, "23", ICON_MATCAP_23, "", ""}, - {ICON_MATCAP_24, "24", ICON_MATCAP_24, "", ""}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "LayerCollectionEngineSettingsClay", "LayerCollectionSettings"); - RNA_def_struct_ui_text(srna, "Collections Clay Engine Settings", "Engine specific settings for this collection"); - - RNA_define_verify_sdna(0); /* not in sdna */ - - /* see RNA_LAYER_ENGINE_GET_SET macro */ - prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_icon_get", "rna_LayerEngineSettings_Clay_matcap_icon_set", NULL); - RNA_def_property_enum_items(prop, clay_matcap_items); - RNA_def_property_ui_text(prop, "Matcap", "Image to use for Material Capture by this material"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "matcap_rotation", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_rotation_get", "rna_LayerEngineSettings_Clay_matcap_rotation_set", NULL); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Matcap Rotation", "Orientation of the matcap on the model"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "matcap_hue", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_hue_get", "rna_LayerEngineSettings_Clay_matcap_hue_set", NULL); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Matcap Hue Shift", "Hue correction of the matcap"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "matcap_saturation", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_saturation_get", "rna_LayerEngineSettings_Clay_matcap_saturation_set", NULL); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Matcap Saturation", "Saturation correction of the matcap"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "matcap_value", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_value_get", "rna_LayerEngineSettings_Clay_matcap_value_set", NULL); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Matcap Value", "Value correction of the matcap"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "ssao_factor_cavity", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_factor_cavity_get", "rna_LayerEngineSettings_Clay_ssao_factor_cavity_set", NULL); - RNA_def_property_ui_text(prop, "Cavity Strength", "Strength of the Cavity effect"); - RNA_def_property_range(prop, 0.0f, 250.0f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "ssao_factor_edge", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_factor_edge_get", "rna_LayerEngineSettings_Clay_ssao_factor_edge_set", NULL); - RNA_def_property_ui_text(prop, "Edge Strength", "Strength of the Edge effect"); - RNA_def_property_range(prop, 0.0f, 250.0f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "ssao_distance", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_distance_get", "rna_LayerEngineSettings_Clay_ssao_distance_set", NULL); - RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the Cavity/Edge effect"); - RNA_def_property_range(prop, 0.0f, 100000.0f); - RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "ssao_attenuation", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_attenuation_get", "rna_LayerEngineSettings_Clay_ssao_attenuation_set", NULL); - RNA_def_property_ui_text(prop, "Attenuation", "Attenuation constant"); - RNA_def_property_range(prop, 1.0f, 100000.0f); - RNA_def_property_ui_range(prop, 1.0f, 100.0f, 1, 3); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - prop = RNA_def_property(srna, "hair_brightness_randomness", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_hair_brightness_randomness_get", "rna_LayerEngineSettings_Clay_hair_brightness_randomness_set", NULL); - RNA_def_property_ui_text(prop, "Hair Brightness Randomness", "Brightness randomness for hair"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_LayerCollectionEngineSettings_update"); - - RNA_define_verify_sdna(1); /* not in sdna */ -} -#endif /* WITH_CLAY_ENGINE */ - -static void rna_def_view_layer_settings(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - FunctionRNA *func; - PropertyRNA *parm; - - srna = RNA_def_struct(brna, "ViewLayerSettings", NULL); - RNA_def_struct_sdna(srna, "IDProperty"); - RNA_def_struct_ui_text(srna, "Scene Layer Settings", - "Engine specific settings that can be overriden by ViewLayer"); - RNA_def_struct_refine_func(srna, "rna_ViewLayerSettings_refine"); - - RNA_define_verify_sdna(0); - - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_string_funcs(prop, "rna_ViewLayerSettings_name_get", "rna_ViewLayerSettings_name_length", NULL); - RNA_def_property_ui_text(prop, "Name", "Engine Name"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_struct_name_property(srna, prop); - - func = RNA_def_function(srna, "use", "rna_ViewLayerSettings_use"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Initialize this property to use"); - parm = RNA_def_string(func, "identifier", NULL, 0, "Property Name", "Name of the property to set"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - - func = RNA_def_function(srna, "unuse", "rna_ViewLayerSettings_unuse"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Remove the property"); - parm = RNA_def_string(func, "identifier", NULL, 0, "Property Name", "Name of the property to unset"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - -#ifdef WITH_CLAY_ENGINE - rna_def_view_layer_engine_settings_clay(brna); -#endif - rna_def_view_layer_engine_settings_eevee(brna); - - RNA_define_verify_sdna(1); -} - -static void rna_def_layer_collection_settings(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - FunctionRNA *func; - PropertyRNA *parm; - - srna = RNA_def_struct(brna, "LayerCollectionSettings", NULL); - RNA_def_struct_sdna(srna, "IDProperty"); - RNA_def_struct_ui_text(srna, "Layer Collection Settings", - "Engine specific settings that can be overriden by LayerCollection"); - RNA_def_struct_refine_func(srna, "rna_LayerCollectionSettings_refine"); - - RNA_define_verify_sdna(0); - - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_string_funcs(prop, "rna_LayerCollectionSettings_name_get", "rna_LayerCollectionSettings_name_length", NULL); - RNA_def_property_ui_text(prop, "Name", "Engine Name"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_struct_name_property(srna, prop); - - func = RNA_def_function(srna, "use", "rna_LayerCollectionSettings_use"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Initialize this property to use"); - parm = RNA_def_string(func, "identifier", NULL, 0, "Property Name", "Name of the property to set"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - - func = RNA_def_function(srna, "unuse", "rna_LayerCollectionSettings_unuse"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Remove the property"); - parm = RNA_def_string(func, "identifier", NULL, 0, "Property Name", "Name of the property to unset"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - -#ifdef WITH_CLAY_ENGINE - rna_def_layer_collection_engine_settings_clay(brna); -#endif - - RNA_define_verify_sdna(1); -} - static void rna_def_layer_collection(BlenderRNA *brna) { StructRNA *srna; @@ -1218,10 +224,10 @@ static void rna_def_layer_collection(BlenderRNA *brna) RNA_def_property_struct_type(prop, "LayerCollection"); RNA_def_property_ui_text(prop, "Children", "Child layer collections"); - prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", LAYER_COLLECTION_EXCLUDE); + prop = RNA_def_property(srna, "exclude", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_EXCLUDE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Use", "Use collection in this view layer"); + RNA_def_property_ui_text(prop, "Exclude", "Exclude collection from view layer"); RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_use_update"); } @@ -1362,8 +368,6 @@ void RNA_def_view_layer(BlenderRNA *brna) rna_def_object_base(brna); RNA_define_animate_sdna(true); /* *** Animated *** */ - rna_def_view_layer_settings(brna); - rna_def_layer_collection_settings(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index c0860c8fd7d..cbd87fb0666 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -32,6 +32,7 @@ #include <limits.h> #include "DNA_material_types.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_cloth_types.h" @@ -45,6 +46,8 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "BKE_mesh.h" + #include "BLI_string_utils.h" #include "BLT_translation.h" @@ -179,7 +182,7 @@ static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, ParticleSy for (md = ob->modifiers.first; md; md = md->next) { if (md->type == eModifierType_ParticleSystem) { psmd = (ParticleSystemModifierData *) md; - if (psmd && psmd->dm_final && psmd->psys) { + if (psmd && psmd->mesh_final && psmd->psys) { psys = psmd->psys; for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { /* hairkeys are stored sequentially in memory, so we can @@ -206,15 +209,15 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu rna_ParticleHairKey_location_object_info(ptr, &psmd, &pa); if (pa) { - DerivedMesh *hairdm = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_dm : NULL; + Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL; - if (hairdm) { - MVert *mvert = CDDM_get_vert(hairdm, pa->hair_index + (hkey - pa->hair)); + if (hair_mesh) { + MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)]; copy_v3_v3(values, mvert->co); } else { float hairmat[4][4]; - psys_mat_hair_to_object(ob, psmd->dm_final, psmd->psys->part->from, pa, hairmat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); copy_v3_v3(values, hkey->co); mul_m4_v3(hairmat, values); } @@ -234,17 +237,17 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float rna_ParticleHairKey_location_object_info(ptr, &psmd, &pa); if (pa) { - DerivedMesh *hairdm = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_dm : NULL; + Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL; - if (hairdm) { - MVert *mvert = CDDM_get_vert(hairdm, pa->hair_index + (hkey - pa->hair)); + if (hair_mesh) { + MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)]; copy_v3_v3(mvert->co, values); } else { float hairmat[4][4]; float imat[4][4]; - psys_mat_hair_to_object(ob, psmd->dm_final, psmd->psys->part->from, pa, hairmat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); copy_v3_v3(hkey->co, values); mul_m4_v3(imat, hkey->co); @@ -259,15 +262,15 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, Object *object, Part float n_co[3]) { - DerivedMesh *hairdm = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_dm : NULL; + Mesh *hair_mesh = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_mesh : NULL; if (particle) { - if (hairdm) { - MVert *mvert = CDDM_get_vert(hairdm, particle->hair_index + (hairkey - particle->hair)); + if (hair_mesh) { + MVert *mvert = &hair_mesh->mvert[particle->hair_index + (hairkey - particle->hair)]; copy_v3_v3(n_co, mvert->co); } else { float hairmat[4][4]; - psys_mat_hair_to_object(object, modifier->dm_final, modifier->psys->part->from, particle, hairmat); + psys_mat_hair_to_object(object, modifier->mesh_final, modifier->psys->part->from, particle, hairmat); copy_v3_v3(n_co, hairkey->co); mul_m4_v3(hairmat, n_co); } @@ -286,14 +289,14 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, ReportList *repor int num = particle->num_dmcache; int from = modifier->psys->part->from; - if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPUV)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); return; } - DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ if (num == DMCACHE_NOTFOUND) - if (particle->num < modifier->dm_final->getNumTessFaces(modifier->dm_final)) + if (particle->num < modifier->mesh_final->totface) num = particle->num; /* get uvco */ @@ -303,8 +306,8 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, ReportList *repor MFace *mface; MTFace *mtface; - mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE); - mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MTFACE, 0); + mface = modifier->mesh_final->mface; + mtface = modifier->mesh_final->mtface; if (mface && mtface) { mtface += num; @@ -423,9 +426,9 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys int totvert; int num = -1; - DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ - totface = modifier->dm_final->getNumTessFaces(modifier->dm_final); - totvert = modifier->dm_final->getNumVerts(modifier->dm_final); + BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + totface = modifier->mesh_final->totface; + totvert = modifier->mesh_final->totvert; /* 1. check that everything is ok & updated */ if (!particlesystem || !totface) { @@ -455,7 +458,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE); + MFace *mface = modifier->mesh_final->mface; *r_fuv = &particle->fuv; @@ -497,7 +500,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE); + MFace *mface = modifier->mesh_final->mface; *r_fuv = &parent->fuv; @@ -521,7 +524,7 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, int uv_no, float r_uv[2]) { - if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPUV)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); zero_v2(r_uv); return; @@ -538,8 +541,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep zero_v2(r_uv); } else { - MFace *mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE); - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MTFACE, uv_no); + MFace *mface = &modifier->mesh_final->mface[num]; + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MTFACE, uv_no); psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv); } @@ -550,7 +553,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, int vcol_no, float r_mcol[3]) { - if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPCOL)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPCOL)) { BKE_report(reports, RPT_ERROR, "Mesh has no VCol data"); zero_v3(r_mcol); return; @@ -567,8 +570,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R zero_v3(r_mcol); } else { - MFace *mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE); - MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MCOL, vcol_no); + MFace *mface = &modifier->mesh_final->mface[num]; + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MCOL, vcol_no); MCol mcol; psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol); diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index ae774f8d41a..b4fc1b4eeb0 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -264,23 +264,6 @@ static void engine_update_script_node(RenderEngine *engine, struct bNodeTree *nt RNA_parameter_list_free(&list); } -static void engine_collection_settings_create(RenderEngine *engine, struct IDProperty *props) -{ - extern FunctionRNA rna_RenderEngine_collection_settings_create_func; - PointerRNA ptr; - ParameterList list; - FunctionRNA *func; - - RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); - func = &rna_RenderEngine_collection_settings_create_func; - - RNA_parameter_list_create(&list, &ptr, func); - RNA_parameter_set_lookup(&list, "props", &props); - engine->type->ext.call(NULL, &ptr, func, &list); - - RNA_parameter_list_free(&list); -} - static void engine_update_render_passes(RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer) { extern FunctionRNA rna_RenderEngine_update_render_passes_func; @@ -366,9 +349,8 @@ static StructRNA *rna_RenderEngine_register( et->render_to_view = (have_function[4]) ? engine_render_to_view : NULL; et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL; et->update_render_passes = (have_function[6]) ? engine_update_render_passes : NULL; - et->collection_settings_create = (have_function[7]) ? engine_collection_settings_create : NULL; - RE_engines_register(bmain, et); + RE_engines_register(et); return et->ext.srna; } @@ -560,13 +542,6 @@ static void rna_def_render_engine(BlenderRNA *brna) parm = RNA_def_pointer(func, "scene", "Scene", "", ""); parm = RNA_def_pointer(func, "renderlayer", "ViewLayer", "", ""); - /* per-collection engine settings initialization */ - func = RNA_def_function(srna, "collection_settings_create", NULL); - RNA_def_function_ui_description(func, "Create the per collection settings for the engine"); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); - parm = RNA_def_pointer(func, "collection_settings", "LayerCollectionSettings", "", ""); - RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); - /* tag for redraw */ func = RNA_def_function(srna, "tag_redraw", "engine_tag_redraw"); RNA_def_function_ui_description(func, "Request redraw for viewport rendering"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f31ee053ffd..8a44fc8edad 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -948,6 +948,11 @@ static void rna_Scene_all_keyingsets_next(CollectionPropertyIterator *iter) iter->valid = (internal->link != NULL); } +static char *rna_SceneEEVEE_path(PointerRNA *UNUSED(ptr)) +{ + return BLI_strdup("eevee"); +} + static int rna_RenderSettings_stereoViews_skip(CollectionPropertyIterator *iter, void *UNUSED(data)) { ListBaseIterator *internal = &iter->internal.listbase; @@ -5673,6 +5678,34 @@ static void rna_def_scene_display(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static const EnumPropertyItem clay_matcap_items[] = { + {1, "01", ICON_MATCAP_01, "", ""}, + {2, "02", ICON_MATCAP_02, "", ""}, + {3, "03", ICON_MATCAP_03, "", ""}, + {4, "04", ICON_MATCAP_04, "", ""}, + {5, "05", ICON_MATCAP_05, "", ""}, + {6, "06", ICON_MATCAP_06, "", ""}, + {7, "07", ICON_MATCAP_07, "", ""}, + {8, "08", ICON_MATCAP_08, "", ""}, + {9, "09", ICON_MATCAP_09, "", ""}, + {10, "10", ICON_MATCAP_10, "", ""}, + {11, "11", ICON_MATCAP_11, "", ""}, + {12, "12", ICON_MATCAP_12, "", ""}, + {13, "13", ICON_MATCAP_13, "", ""}, + {14, "14", ICON_MATCAP_14, "", ""}, + {15, "15", ICON_MATCAP_15, "", ""}, + {16, "16", ICON_MATCAP_16, "", ""}, + {17, "17", ICON_MATCAP_17, "", ""}, + {19, "18", ICON_MATCAP_18, "", ""}, + {19, "19", ICON_MATCAP_19, "", ""}, + {20, "20", ICON_MATCAP_20, "", ""}, + {21, "21", ICON_MATCAP_21, "", ""}, + {22, "22", ICON_MATCAP_22, "", ""}, + {23, "23", ICON_MATCAP_23, "", ""}, + {24, "24", ICON_MATCAP_24, "", ""}, + {0, NULL, 0, NULL, NULL} + }; + static float default_light_direction[3] = {-0.577350269, -0.577350269, 0.577350269}; srna = RNA_def_struct(brna, "SceneDisplay", NULL); @@ -5696,6 +5729,448 @@ static void rna_def_scene_display(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_set_update"); +#ifdef WITH_CLAY_ENGINE + /* Matcap. */ + prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, clay_matcap_items); + RNA_def_property_enum_default(prop, 1); + RNA_def_property_ui_text(prop, "Matcap", "Image to use for Material Capture by this material"); + + prop = RNA_def_property(srna, "matcap_rotation", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.0f); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Matcap Rotation", "Orientation of the matcap on the model"); + + prop = RNA_def_property(srna, "matcap_hue", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Matcap Hue Shift", "Hue correction of the matcap"); + + prop = RNA_def_property(srna, "matcap_saturation", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Matcap Saturation", "Saturation correction of the matcap"); + + prop = RNA_def_property(srna, "matcap_value", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Matcap Value", "Value correction of the matcap"); + + prop = RNA_def_property(srna, "matcap_ssao_factor_cavity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Cavity Strength", "Strength of the Cavity effect"); + RNA_def_property_range(prop, 0.0f, 250.0f); + + prop = RNA_def_property(srna, "matcap_ssao_factor_edge", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Edge Strength", "Strength of the Edge effect"); + RNA_def_property_range(prop, 0.0f, 250.0f); + + prop = RNA_def_property(srna, "matcap_ssao_distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 0.2f); + RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the Cavity/Edge effect"); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); + + prop = RNA_def_property(srna, "matcap_ssao_attenuation", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Attenuation", "Attenuation constant"); + RNA_def_property_range(prop, 1.0f, 100000.0f); + RNA_def_property_ui_range(prop, 1.0f, 100.0f, 1, 3); + + prop = RNA_def_property(srna, "matcap_ssao_samples", PROP_INT, PROP_NONE); + RNA_def_property_int_default(prop, 16); + RNA_def_property_ui_text(prop, "Samples", "Number of samples"); + RNA_def_property_range(prop, 1, 500); + + prop = RNA_def_property(srna, "matcap_hair_brightness_randomness", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 0.0f); + RNA_def_property_ui_text(prop, "Hair Brightness Randomness", "Brightness randomness for hair"); + RNA_def_property_range(prop, 0.0f, 1.0f); +#endif +} + +static void rna_def_scene_eevee(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static const EnumPropertyItem eevee_shadow_method_items[] = { + {SHADOW_ESM, "ESM", 0, "ESM", "Exponential Shadow Mapping"}, + {SHADOW_VSM, "VSM", 0, "VSM", "Variance Shadow Mapping"}, + {0, NULL, 0, NULL, NULL} + }; + + static const EnumPropertyItem eevee_shadow_size_items[] = { + {64, "64", 0, "64px", ""}, + {128, "128", 0, "128px", ""}, + {256, "256", 0, "256px", ""}, + {512, "512", 0, "512px", ""}, + {1024, "1024", 0, "1024px", ""}, + {2048, "2048", 0, "2048px", ""}, + {4096, "4096", 0, "4096px", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static const EnumPropertyItem eevee_gi_visibility_size_items[] = { + {8, "8", 0, "8px", ""}, + {16, "16", 0, "16px", ""}, + {32, "32", 0, "32px", ""}, + {64, "64", 0, "64px", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static const EnumPropertyItem eevee_volumetric_tile_size_items[] = { + {2, "2", 0, "2px", ""}, + {4, "4", 0, "4px", ""}, + {8, "8", 0, "8px", ""}, + {16, "16", 0, "16px", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static float default_bloom_color[3] = {1.0f, 1.0f, 1.0f}; + + srna = RNA_def_struct(brna, "SceneEEVEE", NULL); + RNA_def_struct_path_func(srna, "rna_SceneEEVEE_path"); + RNA_def_struct_ui_text(srna, "Scene Display", "Scene display settings for 3d viewport"); + + /* Indirect Lighting */ + prop = RNA_def_property(srna, "gi_diffuse_bounces", PROP_INT, PROP_NONE); + RNA_def_property_int_default(prop, 3); + RNA_def_property_ui_text(prop, "Diffuse Bounces", "Number of time the light is reinjected inside light grids, " + "0 disable indirect diffuse light"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "gi_cubemap_resolution", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, eevee_shadow_size_items); + RNA_def_property_enum_default(prop, 512); + RNA_def_property_ui_text(prop, "Cubemap Size", "Size of every cubemaps"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "gi_visibility_resolution", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, eevee_gi_visibility_size_items); + RNA_def_property_enum_default(prop, 32); + RNA_def_property_ui_text(prop, "Irradiance Visibility Size", + "Size of the shadow map applied to each irradiance sample"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Temporal Anti-Aliasing (super sampling) */ + prop = RNA_def_property(srna, "taa_samples", PROP_INT, PROP_NONE); + RNA_def_property_int_default(prop, 16); + RNA_def_property_ui_text(prop, "Viewport Samples", "Number of samples, unlimited if 0"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "taa_render_samples", PROP_INT, PROP_NONE); + RNA_def_property_int_default(prop, 64); + RNA_def_property_ui_text(prop, "Render Samples", "Number of samples per pixels for rendering"); + RNA_def_property_range(prop, 1, INT_MAX); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "taa_reprojection", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_TAA_REPROJECTION); + RNA_def_property_boolean_default(prop, 1); + RNA_def_property_ui_text(prop, "Viewport Denoising", "Denoise image using temporal reprojection " + "(can leave some ghosting)"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Screen Space Subsurface Scattering */ + prop = RNA_def_property(srna, "sss_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSS_ENABLED); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Subsurface Scattering", "Enable screen space subsurface scattering"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "sss_samples", PROP_INT, PROP_NONE); + RNA_def_property_int_default(prop, 7); + RNA_def_property_ui_text(prop, "Samples", "Number of samples to compute the scattering effect"); + RNA_def_property_range(prop, 1, 32); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "sss_jitter_threshold", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.3f); + RNA_def_property_ui_text(prop, "Jitter Threshold", "Rotate samples that are below this threshold"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "sss_separate_albedo", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSS_SEPARATE_ALBEDO); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Separate Albedo", "Avoid albedo being blured by the subsurface scattering " + "but uses more video memory"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Screen Space Reflection */ + prop = RNA_def_property(srna, "ssr_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_ENABLED); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Screen Space Reflections", "Enable screen space reflection"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "ssr_refraction", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_REFRACTION); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Screen Space Refractions", "Enable screen space Refractions"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "ssr_halfres", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_HALF_RESOLUTION); + RNA_def_property_boolean_default(prop, 1); + RNA_def_property_ui_text(prop, "Half Res Trace", "Raytrace at a lower resolution"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "ssr_quality", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.25f); + RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the screen space raytracing"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "ssr_max_roughness", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_ui_text(prop, "Max Roughness", "Do not raytrace reflections for roughness above this value"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "ssr_thickness", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_default(prop, 0.2f); + RNA_def_property_ui_text(prop, "Thickness", "Pixel thickness used to detect intersection"); + RNA_def_property_range(prop, 1e-6f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 5, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "ssr_border_fade", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.075f); + RNA_def_property_ui_text(prop, "Edge Fading", "Screen percentage used to fade the SSR"); + RNA_def_property_range(prop, 0.0f, 0.5f); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "ssr_firefly_fac", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 10.0f); + RNA_def_property_ui_text(prop, "Clamp", "Clamp pixel intensity to remove noise (0 to disabled)"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Volumetrics */ + prop = RNA_def_property(srna, "volumetric_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_ENABLED); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Volumetrics", "Enable scattering and absorbance of volumetric material"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_start", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_default(prop, 0.1f); + RNA_def_property_ui_text(prop, "Start", "Start distance of the volumetric effect"); + RNA_def_property_range(prop, 1e-6f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_end", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_default(prop, 100.0f); + RNA_def_property_ui_text(prop, "End", "End distance of the volumetric effect"); + RNA_def_property_range(prop, 1e-6f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_tile_size", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_default(prop, 8); + RNA_def_property_enum_items(prop, eevee_volumetric_tile_size_items); + RNA_def_property_ui_text(prop, "Tile Size", "Control the quality of the volumetric effects " + "(lower size increase vram usage and quality)"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_samples", PROP_INT, PROP_NONE); + RNA_def_property_int_default(prop, 64); + RNA_def_property_ui_text(prop, "Samples", "Number of samples to compute volumetric effects"); + RNA_def_property_range(prop, 1, 256); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_sample_distribution", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.8f); + RNA_def_property_ui_text(prop, "Exponential Sampling", "Distribute more samples closer to the camera"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_lights", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_LIGHTS); + RNA_def_property_boolean_default(prop, 1); + RNA_def_property_ui_text(prop, "Volumetric Lighting", "Enable scene lamps interactions with volumetrics"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_light_clamp", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 0.0f); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_text(prop, "Clamp", "Maximum light contribution, reducing noise"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_shadows", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_SHADOWS); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Volumetric Shadows", "Generate shadows from volumetric material (Very expensive)"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_shadow_samples", PROP_INT, PROP_NONE); + RNA_def_property_int_default(prop, 16); + RNA_def_property_range(prop, 1, 128); + RNA_def_property_ui_text(prop, "Volumetric Shadow Samples", "Number of samples to compute volumetric shadowing"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "volumetric_colored_transmittance", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_COLORED); + RNA_def_property_boolean_default(prop, 1); + RNA_def_property_ui_text(prop, "Colored Transmittance", "Enable wavelength dependent volumetric transmittance"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Ambient Occlusion */ + prop = RNA_def_property(srna, "gtao_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_ENABLED); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Ambient Occlusion", "Enable ambient occlusion to simulate medium scale indirect shadowing"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "gtao_use_bent_normals", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_BENT_NORMALS); + RNA_def_property_boolean_default(prop, 1); + RNA_def_property_ui_text(prop, "Bent Normals", "Compute main non occluded direction to sample the environment"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "gtao_bounce", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_BOUNCE); + RNA_def_property_boolean_default(prop, 1); + RNA_def_property_ui_text(prop, "Bounces Approximation", "An approximation to simulate light bounces " + "giving less occlusion on brighter objects"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "gtao_factor", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Factor", "Factor for ambient occlusion blending"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 2); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "gtao_quality", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.25f); + RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the horizon search"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "gtao_distance", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_default(prop, 0.2f); + RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the ambient occlusion effect"); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Depth of Field */ + prop = RNA_def_property(srna, "dof_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_DOF_ENABLED); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Depth of Field", "Enable depth of field using the values from the active camera"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "bokeh_max_size", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 100.0f); + RNA_def_property_ui_text(prop, "Max Size", "Max size of the bokeh shape for the depth of field (lower is faster)"); + RNA_def_property_range(prop, 0.0f, 2000.0f); + RNA_def_property_ui_range(prop, 2.0f, 200.0f, 1, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "bokeh_threshold", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Sprite Threshold", "Brightness threshold for using sprite base depth of field"); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Bloom */ + prop = RNA_def_property(srna, "bloom_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_BLOOM_ENABLED); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Bloom", "High brighness pixels generate a glowing effect"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "bloom_threshold", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.8f); + RNA_def_property_ui_text(prop, "Threshold", "Filters out pixels under this level of brightness"); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "bloom_color", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_array_default(prop, default_bloom_color); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Color", "Color applied to the bloom effect"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "bloom_knee", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_ui_text(prop, "Knee", "Makes transition between under/over-threshold gradual"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "bloom_radius", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 6.5f); + RNA_def_property_ui_text(prop, "Radius", "Bloom spread distance"); + RNA_def_property_range(prop, 0.0f, 100.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "bloom_clamp", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Clamp", "Maximum intensity a bloom pixel can have"); + RNA_def_property_range(prop, 0.0f, 1000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "bloom_intensity", PROP_FLOAT, PROP_UNSIGNED); + RNA_def_property_float_default(prop, 0.8f); + RNA_def_property_ui_text(prop, "Intensity", "Blend factor"); + RNA_def_property_range(prop, 0.0f, 10000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Motion blur */ + prop = RNA_def_property(srna, "motion_blur_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_MOTION_BLUR_ENABLED); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "Motion Blur", "Enable motion blur effect (only in camera view)"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_default(prop, 8); + RNA_def_property_ui_text(prop, "Samples", "Number of samples to take with motion blur"); + RNA_def_property_range(prop, 1, 64); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close"); + RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 2); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + /* Shadows */ + prop = RNA_def_property(srna, "shadow_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_default(prop, SHADOW_ESM); + RNA_def_property_enum_items(prop, eevee_shadow_method_items); + RNA_def_property_ui_text(prop, "Method", "Technique use to compute the shadows"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "shadow_cube_size", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_default(prop, 512); + RNA_def_property_enum_items(prop, eevee_shadow_size_items); + RNA_def_property_ui_text(prop, "Cube Shadows Resolution", "Size of point and area lamps shadow maps"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "shadow_cascade_size", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_default(prop, 1024); + RNA_def_property_enum_items(prop, eevee_shadow_size_items); + RNA_def_property_ui_text(prop, "Directional Shadows Resolution", "Size of sun lamps shadow maps"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); + + prop = RNA_def_property(srna, "shadow_high_bitdepth", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHADOW_HIGH_BITDEPTH); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_ui_text(prop, "High Bitdepth", "Use 32bit shadows"); + RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC); } void RNA_def_scene(BlenderRNA *brna) @@ -6006,19 +6481,6 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "RenderSettings"); RNA_def_property_ui_text(prop, "Render Data", ""); - /* Render Engine Data */ - prop = RNA_def_property(srna, "layer_properties", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "layer_properties->data.group", NULL); - RNA_def_property_struct_type(prop, "ViewLayerSettings"); - RNA_def_property_ui_text(prop, "Layer Settings", - "Engine specific render settings to be overridden by layers"); - - prop = RNA_def_property(srna, "collection_properties", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "collection_properties->data.group", NULL); - RNA_def_property_struct_type(prop, "LayerCollectionSettings"); - RNA_def_property_ui_text(prop, "Collection Settings", - "Engine specific render settings to be overridden by collections"); - /* Safe Areas */ prop = RNA_def_property(srna, "safe_areas", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "safe_areas"); @@ -6153,6 +6615,11 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "SceneDisplay"); RNA_def_property_ui_text(prop, "Scene Display", "Scene display settings for 3d viewport"); + /* EEVEE */ + prop = RNA_def_property(srna, "eevee", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "SceneEEVEE"); + RNA_def_property_ui_text(prop, "EEVEE", "EEVEE settings for the scene"); + /* Nestled Data */ /* *** Non-Animated *** */ RNA_define_animate_sdna(false); @@ -6168,6 +6635,7 @@ void RNA_def_scene(BlenderRNA *brna) rna_def_selected_uv_element(brna); rna_def_display_safe_areas(brna); rna_def_scene_display(brna); + rna_def_scene_eevee(brna); RNA_define_animate_sdna(true); /* *** Animated *** */ rna_def_scene_render_data(brna); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 6c261d06035..1d1dbdb8d9c 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -37,6 +37,8 @@ #include "BKE_node.h" #include "BKE_studiolight.h" +#include "BLI_math.h" + #include "DNA_action_types.h" #include "DNA_key_types.h" #include "DNA_material_types.h" @@ -181,29 +183,39 @@ const EnumPropertyItem rna_enum_viewport_lighting_items[] = { }; static const EnumPropertyItem rna_enum_studio_light_items[] = { - {0, "STUDIOLIGHT_01", 0, "", ""}, - {1, "STUDIOLIGHT_02", 0, "", ""}, - {2, "STUDIOLIGHT_03", 0, "", ""}, - {3, "STUDIOLIGHT_04", 0, "", ""}, - {4, "STUDIOLIGHT_05", 0, "", ""}, - {5, "STUDIOLIGHT_06", 0, "", ""}, - {6, "STUDIOLIGHT_07", 0, "", ""}, - {7, "STUDIOLIGHT_08", 0, "", ""}, - {8, "STUDIOLIGHT_09", 0, "", ""}, - {9, "STUDIOLIGHT_10", 0, "", ""}, - {10, "STUDIOLIGHT_11", 0, "", ""}, - {11, "STUDIOLIGHT_12", 0, "", ""}, - {12, "STUDIOLIGHT_13", 0, "", ""}, - {13, "STUDIOLIGHT_14", 0, "", ""}, - {14, "STUDIOLIGHT_15", 0, "", ""}, - {15, "STUDIOLIGHT_16", 0, "", ""}, - {16, "STUDIOLIGHT_17", 0, "", ""}, - {17, "STUDIOLIGHT_18", 0, "", ""}, - {18, "STUDIOLIGHT_19", 0, "", ""}, - {19, "STUDIOLIGHT_20", 0, "", ""}, + {0, "STUDIOLIGHT_00", 0, "", ""}, + {1, "STUDIOLIGHT_01", 0, "", ""}, + {2, "STUDIOLIGHT_02", 0, "", ""}, + {3, "STUDIOLIGHT_03", 0, "", ""}, + {4, "STUDIOLIGHT_04", 0, "", ""}, + {5, "STUDIOLIGHT_05", 0, "", ""}, + {6, "STUDIOLIGHT_06", 0, "", ""}, + {7, "STUDIOLIGHT_07", 0, "", ""}, + {8, "STUDIOLIGHT_08", 0, "", ""}, + {9, "STUDIOLIGHT_09", 0, "", ""}, + {10, "STUDIOLIGHT_10", 0, "", ""}, + {11, "STUDIOLIGHT_11", 0, "", ""}, + {12, "STUDIOLIGHT_12", 0, "", ""}, + {13, "STUDIOLIGHT_13", 0, "", ""}, + {14, "STUDIOLIGHT_14", 0, "", ""}, + {15, "STUDIOLIGHT_15", 0, "", ""}, + {16, "STUDIOLIGHT_16", 0, "", ""}, + {17, "STUDIOLIGHT_17", 0, "", ""}, + {18, "STUDIOLIGHT_18", 0, "", ""}, + {19, "STUDIOLIGHT_19", 0, "", ""}, + {20, "STUDIOLIGHT_20", 0, "", ""}, + {21, "STUDIOLIGHT_21", 0, "", ""}, + {22, "STUDIOLIGHT_22", 0, "", ""}, + {23, "STUDIOLIGHT_23", 0, "", ""}, + {24, "STUDIOLIGHT_24", 0, "", ""}, + {25, "STUDIOLIGHT_25", 0, "", ""}, + {26, "STUDIOLIGHT_26", 0, "", ""}, + {27, "STUDIOLIGHT_27", 0, "", ""}, + {28, "STUDIOLIGHT_28", 0, "", ""}, + {29, "STUDIOLIGHT_29", 0, "", ""}, {0, NULL, 0, NULL, NULL} }; -#define NUM_STUDIO_LIGHT_ITEMS 20 +#define NUM_STUDIO_LIGHT_ITEMS 30 const EnumPropertyItem rna_enum_clip_editor_mode_items[] = { {SC_MODE_TRACKING, "TRACKING", ICON_ANIM_DATA, "Tracking", "Show tracking and solving tools"}, @@ -686,9 +698,18 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf( return item; } +static int rna_View3DShading_studio_light_orientation_get(PointerRNA *ptr) +{ + View3D *v3d = (View3D *)ptr->data; + StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light); + return sl->flag & (STUDIOLIGHT_ORIENTATION_WORLD|STUDIOLIGHT_ORIENTATION_CAMERA); +} +static void rna_View3DShading_studio_light_orientation_set(PointerRNA *UNUSED(ptr), int UNUSED(value)) +{ +} + static int rna_View3DShading_studio_light_get(PointerRNA *ptr) { - /* XXX: should be stored as string */ View3D *v3d = (View3D *)ptr->data; StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light); return sl->index; @@ -696,7 +717,6 @@ static int rna_View3DShading_studio_light_get(PointerRNA *ptr) static void rna_View3DShading_studio_light_set(PointerRNA *ptr, int value) { - /* XXX: should be stored as string */ View3D *v3d = (View3D *)ptr->data; StudioLight *sl = BKE_studiolight_findindex(value); BLI_strncpy(v3d->shading.studio_light, sl->name, FILE_MAXFILE); @@ -714,6 +734,7 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf( if (totitem < NUM_STUDIO_LIGHT_ITEMS) { RNA_enum_items_add_value(&item, &totitem, rna_enum_studio_light_items, totitem); lastitem = &item[totitem-1]; + lastitem->value = sl->index; lastitem->icon = sl->icon_id; lastitem->name = sl->name; } @@ -2052,33 +2073,23 @@ static void rna_def_space_outliner(BlenderRNA *brna) static const EnumPropertyItem display_mode_items[] = { {SO_SCENES, "SCENES", 0, "Scenes", "Display scenes and their view layers, collections and objects"}, - {SO_COLLECTIONS, "COLLECTIONS", 0, "Collections", "Display collections and objects in the view layer"}, - {SO_OBJECTS, "OBJECTS", 0, "Objects", "Display objects in the view layer"}, - {SO_VIEW_LAYER, "VIEW_LAYER", 0, "View Layer", "Edit which collections are used in the view layer"}, + {SO_VIEW_LAYER, "VIEW_LAYER", 0, "View Layer", "Display collections and objects in the view layer"}, {SO_SEQUENCE, "SEQUENCE", 0, "Sequence", "Display sequence data-blocks"}, {SO_LIBRARIES, "LIBRARIES", 0, "Blender File", "Display data of current file and linked libraries"}, - {SO_DATABLOCKS, "DATABLOCKS", 0, "Data-Blocks", "Display all raw data-blocks"}, + {SO_DATA_API, "DATA_API", 0, "Data API", "Display low level Blender data and its properties"}, {SO_ID_ORPHANS, "ORPHAN_DATA", 0, "Orphan Data", "Display data-blocks which are unused and/or will be lost when the file is reloaded"}, {0, NULL, 0, NULL, NULL} }; static const EnumPropertyItem filter_state_items[] = { - {SO_FILTER_OB_ALL, "ALL", 0, "All", "Show visible objects"}, + {SO_FILTER_OB_ALL, "ALL", 0, "All", "Show all objects in the view layer"}, {SO_FILTER_OB_VISIBLE, "VISIBLE", 0, "Visible", "Show visible objects"}, {SO_FILTER_OB_SELECTED, "SELECTED", 0, "Selected", "Show selected objects"}, {SO_FILTER_OB_ACTIVE, "ACTIVE", 0, "Active", "Show only the active object"}, {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem filter_collection_items[] = { - {SO_FILTER_COLLECTION_SCENE, "SCENE", 0, "Scene", "Show collections in active scene and view layer"}, - {SO_FILTER_COLLECTION_UNLINKED, "UNLINKED", 0, "Unlinked", "Show collections not used in any scene hierarchy"}, - {SO_FILTER_COLLECTION_ALL, "ALL", 0, "All", "Show all collections in the file"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "SpaceOutliner", "Space"); RNA_def_struct_sdna(srna, "SpaceOops"); RNA_def_struct_ui_text(srna, "Space Outliner", "Outliner space data"); @@ -2140,6 +2151,11 @@ static void rna_def_space_outliner(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Object Children", "Show children"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + prop = RNA_def_property(srna, "use_filter_collection", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "filter", SO_FILTER_NO_COLLECTION); + RNA_def_property_ui_text(prop, "Show Collections", "Show collections"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + /* Filters object state. */ prop = RNA_def_property(srna, "filter_state", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "filter_state"); @@ -2178,11 +2194,16 @@ static void rna_def_space_outliner(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Other Objects", "Show curves, lattices, light probes, fonts, ..."); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); - /* Filters collections state. */ - prop = RNA_def_property(srna, "filter_collection", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, filter_collection_items); - RNA_def_property_ui_text(prop, "Collection Filter", ""); + /* Libraries filter. */ + prop = RNA_def_property(srna, "use_filter_id_type", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "filter", SO_FILTER_ID_TYPE); + RNA_def_property_ui_text(prop, "Filter By Type", "Show only data-blocks of one type"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + + prop = RNA_def_property(srna, "filter_id_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "filter_id_type"); + RNA_def_property_enum_items(prop, rna_enum_id_type_items); + RNA_def_property_ui_text(prop, "Filter ID Type", "Data-block type to show"); } static void rna_def_space_view3d_shading(BlenderRNA *brna) @@ -2198,6 +2219,13 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static const EnumPropertyItem studio_light_orientation_items[] = { + {0, "UNKNOWN", 0, "Unknown", "Studio light has no orientation"}, + {STUDIOLIGHT_ORIENTATION_CAMERA, "CAMERA", 0, "Camera", "Studio light is camera based"}, + {STUDIOLIGHT_ORIENTATION_WORLD, "WORLD", 0, "World", "Studio light is world based"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "View3DShading", NULL); RNA_def_struct_sdna(srna, "View3D"); RNA_def_struct_nested(brna, srna, "SpaceView3D"); @@ -2231,6 +2259,23 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Studiolight", "Studio lighting setup"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "studio_light_orientation", PROP_ENUM, PROP_NONE); + RNA_define_verify_sdna(0); + RNA_def_property_enum_sdna(prop, NULL, "shading.flag"); + RNA_def_property_ui_text(prop, "Studio Light Orientation", "Orientation of the studio light"); + RNA_def_property_enum_items(prop, studio_light_orientation_items); + RNA_def_property_enum_funcs(prop, "rna_View3DShading_studio_light_orientation_get", "rna_View3DShading_studio_light_orientation_set", NULL); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_define_verify_sdna(1); + + prop = RNA_def_property(srna, "studiolight_rot_z", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "shading.studiolight_rot_z"); + RNA_def_property_float_default(prop, 0.0); + RNA_def_property_ui_text(prop, "Studiolight Rotation", "Rotation of the studiolight around the Z-Axis"); + RNA_def_property_range(prop, -M_PI, M_PI); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "color_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "shading.color_type"); RNA_def_property_enum_items(prop, color_type_items); diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index aab6c62ee7e..6688236a558 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1009,7 +1009,7 @@ static DerivedMesh *applyModifier( if (psys == NULL || psys->totpart == 0) return derivedData; if (psys->part == NULL || psys->particles == NULL) return derivedData; - if (psmd->dm_final == NULL) return derivedData; + if (psmd->mesh_final == NULL) return derivedData; DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 26761d8ef91..94adb3d9ebc 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -421,7 +421,7 @@ static void deformVerts( modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ - meshdeformModifier_do(md, ctx->object, mesh, vertexCos, numVerts); + meshdeformModifier_do(md, ctx->object, mesh_src, vertexCos, numVerts); if (mesh_src && mesh_src != mesh) { BKE_id_free(NULL, mesh_src); @@ -437,7 +437,7 @@ static void deformVertsEM( { Mesh *mesh_src = get_mesh(ctx->object, NULL, mesh, NULL, false, false); - meshdeformModifier_do(md, ctx->object, mesh, vertexCos, numVerts); + meshdeformModifier_do(md, ctx->object, mesh_src, vertexCos, numVerts); if (mesh_src && mesh_src != mesh) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 3a781a58634..eee7f0c5561 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -33,6 +33,7 @@ */ +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "MEM_guardedalloc.h" @@ -43,11 +44,11 @@ #include "BLI_string.h" #include "BLI_utildefines.h" -#include "BKE_cdderivedmesh.h" #include "BKE_effect.h" #include "BKE_global.h" #include "BKE_lattice.h" #include "BKE_library_query.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -195,11 +196,11 @@ static void store_float_in_vcol(MLoopCol *vcol, float float_value) vcol->a = 1.0f; } -static DerivedMesh *applyModifier( +static Mesh *applyModifier( ModifierData *md, const ModifierEvalContext *ctx, - DerivedMesh *derivedData) + Mesh *mesh) { - DerivedMesh *dm = derivedData, *result; + Mesh *result; ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md; ParticleSimulationData sim; ParticleSystem *psys = NULL; @@ -222,16 +223,16 @@ static DerivedMesh *applyModifier( if (pimd->ob == ctx->object) { pimd->ob = NULL; - return derivedData; + return mesh; } if (pimd->ob) { psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1); if (psys == NULL || psys->totpart == 0) - return derivedData; + return mesh; } else { - return derivedData; + return mesh; } part_start = use_parents ? 0 : psys->totpart; @@ -243,7 +244,7 @@ static DerivedMesh *applyModifier( part_end += psys->totchild; if (part_end == 0) - return derivedData; + return mesh; sim.depsgraph = ctx->depsgraph; sim.scene = md->scene; @@ -285,10 +286,10 @@ static DerivedMesh *applyModifier( break; } - totvert = dm->getNumVerts(dm); - totpoly = dm->getNumPolys(dm); - totloop = dm->getNumLoops(dm); - totedge = dm->getNumEdges(dm); + totvert = mesh->totvert; + totpoly = mesh->totpoly; + totloop = mesh->totloop; + totedge = mesh->totedge; /* count particles */ maxvert = 0; @@ -311,22 +312,22 @@ static DerivedMesh *applyModifier( if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) { float min[3], max[3]; INIT_MINMAX(min, max); - dm->getMinMax(dm, min, max); + BKE_mesh_minmax(mesh, min, max); min_co = min[track]; max_co = max[track]; } - result = CDDM_from_template(dm, maxvert, maxedge, 0, maxloop, maxpoly); + result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly); - mvert = result->getVertArray(result); - orig_mvert = dm->getVertArray(dm); - mpoly = result->getPolyArray(result); - orig_mpoly = dm->getPolyArray(dm); - mloop = result->getLoopArray(result); - orig_mloop = dm->getLoopArray(dm); + mvert = result->mvert; + orig_mvert = mesh->mvert; + mpoly = result->mpoly; + orig_mpoly = mesh->mpoly; + mloop = result->mloop; + orig_mloop = mesh->mloop; - MLoopCol *mloopcols_index = CustomData_get_layer_named(&result->loopData, CD_MLOOPCOL, pimd->index_layer_name); - MLoopCol *mloopcols_value = CustomData_get_layer_named(&result->loopData, CD_MLOOPCOL, pimd->value_layer_name); + MLoopCol *mloopcols_index = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, pimd->index_layer_name); + MLoopCol *mloopcols_value = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, pimd->value_layer_name); int *vert_part_index = NULL; float *vert_part_value = NULL; if (mloopcols_index != NULL) { @@ -353,7 +354,7 @@ static DerivedMesh *applyModifier( MVert *mv = mvert + vindex; inMV = orig_mvert + k; - DM_copy_vert_data(dm, result, k, p_skip * totvert + k, 1); + CustomData_copy_data(&mesh->vdata, &result->vdata, k, p_skip * totvert + k, 1); *mv = *inMV; if (vert_part_index != NULL) { @@ -405,7 +406,7 @@ static DerivedMesh *applyModifier( ChildParticle *cpa = psys->child + (p - psys->totpart); pa = psys->particles + (between? cpa->pa[0]: cpa->parent); } - psys_mat_hair_to_global(sim.ob, sim.psmd->dm_final, sim.psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat); copy_m3_m4(mat, hairmat); /* to quaternion */ mat3_to_quat(frame, mat); @@ -467,8 +468,8 @@ static DerivedMesh *applyModifier( } /* create edges and adjust edge vertex indices*/ - DM_copy_edge_data(dm, result, 0, p_skip * totedge, totedge); - MEdge *me = CDDM_get_edges(result) + p_skip * totedge; + CustomData_copy_data(&mesh->edata, &result->edata, 0, p_skip * totedge, totedge); + MEdge *me = &result->medge[p_skip * totedge]; for (k = 0; k < totedge; k++, me++) { me->v1 += p_skip * totvert; me->v2 += p_skip * totvert; @@ -480,7 +481,7 @@ static DerivedMesh *applyModifier( MPoly *inMP = orig_mpoly + k; MPoly *mp = mpoly + p_skip * totpoly + k; - DM_copy_poly_data(dm, result, k, p_skip * totpoly + k, 1); + CustomData_copy_data(&mesh->pdata, &result->pdata, k, p_skip * totpoly + k, 1); *mp = *inMP; mp->loopstart += p_skip * totloop; @@ -489,7 +490,7 @@ static DerivedMesh *applyModifier( MLoop *ml = mloop + mp->loopstart; int j = mp->totloop; - DM_copy_loop_data(dm, result, inMP->loopstart, mp->loopstart, j); + CustomData_copy_data(&mesh->ldata, &result->ldata, inMP->loopstart, mp->loopstart, j); for (; j; j--, ml++, inML++) { ml->v = inML->v + (p_skip * totvert); ml->e = inML->e + (p_skip * totedge); @@ -519,7 +520,7 @@ static DerivedMesh *applyModifier( MEM_SAFE_FREE(vert_part_index); MEM_SAFE_FREE(vert_part_value); - result->dirty |= DM_DIRTY_NORMALS; + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; return result; } @@ -539,14 +540,14 @@ ModifierTypeInfo modifierType_ParticleInstance = { /* deformMatrices_DM */ NULL, /* deformVertsEM_DM */ NULL, /* deformMatricesEM_DM*/NULL, - /* applyModifier_DM */ applyModifier, + /* applyModifier_DM */ NULL, /* applyModifierEM_DM */NULL, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* applyModifier */ applyModifier, /* applyModifierEM */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index ad24ce92626..c2493e6d8f3 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -42,6 +42,8 @@ #include "BKE_cdderivedmesh.h" +#include "BKE_mesh.h" +#include "BKE_library.h" #include "BKE_modifier.h" #include "BKE_particle.h" @@ -52,22 +54,20 @@ static void initData(ModifierData *md) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; psmd->psys = NULL; - psmd->dm_final = NULL; - psmd->dm_deformed = NULL; + psmd->mesh_final = NULL; + psmd->mesh_deformed = NULL; psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; } static void freeData(ModifierData *md) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; - if (psmd->dm_final) { - psmd->dm_final->needsFree = true; - psmd->dm_final->release(psmd->dm_final); - psmd->dm_final = NULL; - if (psmd->dm_deformed) { - psmd->dm_deformed->needsFree = true; - psmd->dm_deformed->release(psmd->dm_deformed); - psmd->dm_deformed = NULL; + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_deformed) { + BKE_id_free(NULL, psmd->mesh_deformed); + psmd->mesh_deformed = NULL; } } psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; @@ -87,8 +87,8 @@ static void copyData(const ModifierData *md, ModifierData *target) modifier_copyData_generic(md, target); - tpsmd->dm_final = NULL; - tpsmd->dm_deformed = NULL; + tpsmd->mesh_final = NULL; + tpsmd->mesh_deformed = NULL; tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0; } @@ -101,14 +101,13 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) /* saves the current emitter state for a particle system and calculates particles */ static void deformVerts( ModifierData *md, const ModifierEvalContext *ctx, - DerivedMesh *derivedData, + Mesh *mesh, float (*vertexCos)[3], int UNUSED(numVerts)) { - DerivedMesh *dm = derivedData; + Mesh *mesh_src = mesh; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; ParticleSystem *psys = NULL; - bool needsFree = false; /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */ if (ctx->object->particlesystem.first) @@ -119,27 +118,24 @@ static void deformVerts( if (!psys_check_enabled(ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0)) return; - if (dm == NULL) { - dm = get_dm(ctx->object, NULL, NULL, vertexCos, false, true); - - if (!dm) + if (mesh_src == NULL) { + mesh_src = get_mesh(ctx->object, NULL, NULL, vertexCos, false, true); + if (mesh_src == NULL) { return; - - needsFree = true; + } } /* clear old dm */ - if (psmd->dm_final) { - psmd->dm_final->needsFree = true; - psmd->dm_final->release(psmd->dm_final); - if (psmd->dm_deformed) { - psmd->dm_deformed->needsFree = 1; - psmd->dm_deformed->release(psmd->dm_deformed); - psmd->dm_deformed = NULL; + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_deformed) { + BKE_id_free(NULL, psmd->mesh_deformed); + psmd->mesh_deformed = NULL; } } else if (psmd->flag & eParticleSystemFlag_file_loaded) { - /* in file read dm just wasn't saved in file so no need to reset everything */ + /* in file read mesh just wasn't saved in file so no need to reset everything */ psmd->flag &= ~eParticleSystemFlag_file_loaded; } else { @@ -147,43 +143,49 @@ static void deformVerts( psys->recalc |= PSYS_RECALC_RESET; } - /* make new dm */ - psmd->dm_final = CDDM_copy(dm); - CDDM_apply_vert_coords(psmd->dm_final, vertexCos); - CDDM_calc_normals(psmd->dm_final); + /* make new mesh */ + BKE_id_copy_ex(NULL, &mesh_src->id, (ID **)&psmd->mesh_final, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); + BKE_mesh_apply_vert_coords(psmd->mesh_final, vertexCos); + BKE_mesh_calc_normals(psmd->mesh_final); - if (needsFree) { - dm->needsFree = true; - dm->release(dm); - } + BKE_mesh_tessface_ensure(psmd->mesh_final); - /* protect dm */ - psmd->dm_final->needsFree = false; - - DM_ensure_tessface(psmd->dm_final); - - if (!psmd->dm_final->deformedOnly) { + if (!psmd->mesh_final->runtime.deformed_only) { /* XXX Think we can assume here that if current DM is not only-deformed, ob->deformedOnly has been set. * This is awfully weak though. :| */ if (ctx->object->derivedDeform) { - psmd->dm_deformed = CDDM_copy(ctx->object->derivedDeform); + DM_to_mesh(ctx->object->derivedDeform, psmd->mesh_deformed, ctx->object, CD_MASK_EVERYTHING, false); } else { /* Can happen in some cases, e.g. when rendering from Edit mode... */ - psmd->dm_deformed = CDDM_from_mesh((Mesh *)ctx->object->data); + BKE_id_copy_ex(NULL, &mesh_src->id, (ID **)&psmd->mesh_deformed, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); } - DM_ensure_tessface(psmd->dm_deformed); + BKE_mesh_tessface_ensure(psmd->mesh_deformed); + } + + if (mesh_src != psmd->mesh_final && mesh_src != mesh) { + BKE_id_free(NULL, mesh_src); } /* report change in mesh structure */ - if (psmd->dm_final->getNumVerts(psmd->dm_final) != psmd->totdmvert || - psmd->dm_final->getNumEdges(psmd->dm_final) != psmd->totdmedge || - psmd->dm_final->getNumTessFaces(psmd->dm_final) != psmd->totdmface) + if (psmd->mesh_final->totvert != psmd->totdmvert || + psmd->mesh_final->totedge != psmd->totdmedge || + psmd->mesh_final->totface != psmd->totdmface) { psys->recalc |= PSYS_RECALC_RESET; - psmd->totdmvert = psmd->dm_final->getNumVerts(psmd->dm_final); - psmd->totdmedge = psmd->dm_final->getNumEdges(psmd->dm_final); - psmd->totdmface = psmd->dm_final->getNumTessFaces(psmd->dm_final); + psmd->totdmvert = psmd->mesh_final->totvert; + psmd->totdmedge = psmd->mesh_final->totedge; + psmd->totdmface = psmd->mesh_final->totface; } if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) { @@ -224,14 +226,14 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* copyData */ copyData, - /* deformVerts_DM */ deformVerts, + /* deformVerts_DM */ NULL, /* deformVertsEM_DM */ NULL, /* deformMatrices_DM */ NULL, /* deformMatricesEM_DM*/NULL, /* applyModifier_DM */ NULL, /* applyModifierEM_DM */NULL, - /* deformVerts */ NULL, + /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index f3da8d054ec..c5593cd004e 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -313,6 +313,7 @@ Mesh *get_mesh( LIB_ID_CREATE_NO_DEG_TAG | LIB_ID_COPY_NO_PREVIEW, false); + mesh->runtime.deformed_only = 1; } /* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index efe7db088f8..5acd0a9fcea 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -177,6 +177,7 @@ set(SRC shader/nodes/node_shader_light_falloff.c shader/nodes/node_shader_light_path.c shader/nodes/node_shader_mix_shader.c + shader/nodes/node_shader_shaderToRgb.c shader/nodes/node_shader_normal_map.c shader/nodes/node_shader_object_info.c shader/nodes/node_shader_hair_info.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index e411ceb6a23..3d6a8647628 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -50,6 +50,7 @@ void register_node_type_sh_rgb(void); void register_node_type_sh_mix_rgb(void); void register_node_type_sh_valtorgb(void); void register_node_type_sh_rgbtobw(void); +void register_node_type_sh_shadertorgb(void); void register_node_type_sh_normal(void); void register_node_type_sh_gamma(void); void register_node_type_sh_brightcontrast(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 299c3a627ee..efb8eb66737 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -45,6 +45,7 @@ DefNode( ShaderNode, SH_NODE_VALUE, 0, "VALUE DefNode( ShaderNode, SH_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "MixRGB", "" ) DefNode( ShaderNode, SH_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" ) DefNode( ShaderNode, SH_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" ) +DefNode( ShaderNode, SH_NODE_SHADERTORGB, 0, "SHADERTORGB", ShaderToRGB, "Shader to RGB", "" ) DefNode( ShaderNode, SH_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" ) DefNode( ShaderNode, SH_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" ) DefNode( ShaderNode, SH_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright Contrast", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c b/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c new file mode 100644 index 00000000000..286752f9a10 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c @@ -0,0 +1,61 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Kanzaki Wataru, Kinouti Takahiro + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +static bNodeSocketTemplate sh_node_shadertorgb_in[] = { + { SOCK_SHADER, 1, N_("Shader")}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_shadertorgb_out[] = { + { SOCK_RGBA, 0, N_("Color")}, + { SOCK_FLOAT, 0, N_("Alpha")}, + { -1, 0, "" } +}; + +static int node_shader_gpu_shadertorgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, node, "node_shadertorgb", in, out); +} + +/* node type definition */ +void register_node_type_sh_shadertorgb(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_SHADERTORGB, "Shader to RGB", NODE_CLASS_CONVERTOR, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_shadertorgb_in, sh_node_shadertorgb_out); + node_type_init(&ntype, NULL); + node_type_storage(&ntype, "", NULL, NULL); + node_type_gpu(&ntype, node_shader_gpu_shadertorgb); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index e857d508424..b401eb260d8 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -107,9 +107,6 @@ typedef struct RenderEngineType { void (*update_script_node)(struct RenderEngine *engine, struct bNodeTree *ntree, struct bNode *node); void (*update_render_passes)(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer); - void (*collection_settings_create)(struct RenderEngine *engine, struct IDProperty *props); - void (*render_settings_create)(struct RenderEngine *engine, struct IDProperty *props); - struct DrawEngineType *draw_engine; /* RNA integration */ @@ -187,7 +184,7 @@ void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, s void RE_engines_init(void); void RE_engines_exit(void); -void RE_engines_register(struct Main *bmain, RenderEngineType *render_type); +void RE_engines_register(RenderEngineType *render_type); bool RE_engine_is_opengl(RenderEngineType *render_type); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 1cdf4d3495b..3777845e4db 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -87,9 +87,6 @@ void RE_engines_exit(void) DRW_engines_free(); - BKE_layer_collection_engine_settings_callback_free(); - BKE_view_layer_engine_settings_callback_free(); - for (type = R_engines.first; type; type = next) { next = type->next; @@ -104,19 +101,11 @@ void RE_engines_exit(void) } } -void RE_engines_register(Main *bmain, RenderEngineType *render_type) +void RE_engines_register(RenderEngineType *render_type) { if (render_type->draw_engine) { DRW_engine_register(render_type->draw_engine); } - if (render_type->collection_settings_create) { - BKE_layer_collection_engine_settings_callback_register( - bmain, render_type->idname, render_type->collection_settings_create); - } - if (render_type->render_settings_create) { - BKE_view_layer_engine_settings_callback_register( - bmain, render_type->idname, render_type->render_settings_create); - } BLI_addtail(&R_engines, render_type); } diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index c7cd381747a..af70b3f1a5b 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -811,7 +811,6 @@ void wm_draw_update(bContext *C) wm_window_make_drawable(wm, win); /* notifiers for screen redraw */ - ED_screen_set_active_region(C, &win->eventstate->x); ED_screen_ensure_updated(wm, win, screen); wm_draw_window(C, win); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index b141433a58f..7963bf16534 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2818,7 +2818,7 @@ void wm_event_do_handlers(bContext *C) /* Note: setting subwin active should be done here, after modal handlers have been done */ if (event->type == MOUSEMOVE) { /* state variables in screen, cursors. Also used in wm_draw.c, fails for modal handlers though */ - ED_screen_set_active_region(C, &event->x); + ED_screen_set_active_region(C, win, &event->x); /* for regions having custom cursors */ wm_paintcursor_test(C, event); } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 2d94cc1dae7..2c28819ee58 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -608,6 +608,16 @@ void WM_window_set_dpi(wmWindow *win) BLF_default_dpi(U.pixelsize * U.dpi); } +static void wm_window_ensure_eventstate(wmWindow *win) +{ + if (win->eventstate) { + return; + } + + win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state"); + wm_get_cursor_position(win, &win->eventstate->x, &win->eventstate->y); +} + /* belongs to below */ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wmWindow *win) { @@ -651,8 +661,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm win->ghostwin = ghostwin; GHOST_SetWindowUserData(ghostwin, win); /* pointer back */ - if (win->eventstate == NULL) - win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state"); + wm_window_ensure_eventstate(win); /* store actual window size in blender window */ bounds = GHOST_GetClientBounds(win->ghostwin); @@ -758,8 +767,7 @@ void wm_window_ghostwindows_ensure(wmWindowManager *wm) wm_window_ghostwindow_add(wm, "Blender", win); } /* happens after fileread */ - if (win->eventstate == NULL) - win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state"); + wm_window_ensure_eventstate(win); /* add keymap handlers (1 handler for all keys in map!) */ keymap = WM_keymap_find(wm->defaultconf, "Window", 0, 0); diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 3abfe29c000..92eb50831aa 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -630,4 +630,6 @@ if(WITH_CODEC_FFMPEG) endif() add_subdirectory(collada) -add_subdirectory(view_layer) + +# TODO: disabled for now after collection unification +# add_subdirectory(view_layer) diff --git a/tests/python/view_layer/CMakeLists.txt b/tests/python/view_layer/CMakeLists.txt index 9cb33420ac5..69f7af20ad2 100644 --- a/tests/python/view_layer/CMakeLists.txt +++ b/tests/python/view_layer/CMakeLists.txt @@ -65,15 +65,15 @@ VIEW_LAYER_TEST(background_set) VIEW_LAYER_TEST(collection_new_sync) VIEW_LAYER_TEST(collection_rename_a) VIEW_LAYER_TEST(collection_rename_b) -VIEW_LAYER_TEST(evaluation_render_settings_a) -VIEW_LAYER_TEST(evaluation_render_settings_b) -VIEW_LAYER_TEST(evaluation_render_settings_c) -VIEW_LAYER_TEST(evaluation_render_settings_d) -VIEW_LAYER_TEST(evaluation_render_settings_e) -VIEW_LAYER_TEST(evaluation_render_settings_f) -VIEW_LAYER_TEST(evaluation_render_settings_g) -VIEW_LAYER_TEST(evaluation_render_settings_h) -VIEW_LAYER_TEST(evaluation_render_settings_i) +#VIEW_LAYER_TEST(evaluation_render_settings_a) +#VIEW_LAYER_TEST(evaluation_render_settings_b) +#VIEW_LAYER_TEST(evaluation_render_settings_c) +#VIEW_LAYER_TEST(evaluation_render_settings_d) +#VIEW_LAYER_TEST(evaluation_render_settings_e) +#VIEW_LAYER_TEST(evaluation_render_settings_f) +#VIEW_LAYER_TEST(evaluation_render_settings_g) +#VIEW_LAYER_TEST(evaluation_render_settings_h) +#VIEW_LAYER_TEST(evaluation_render_settings_i) VIEW_LAYER_TEST(evaluation_visibility_a) VIEW_LAYER_TEST(evaluation_visibility_b) VIEW_LAYER_TEST(evaluation_visibility_c) |