UI: Asset Shelf (Experimental Feature) #104831
|
@ -5,6 +5,8 @@ from __future__ import annotations
|
|||
import bpy
|
||||
import _cycles
|
||||
|
||||
from bpy.app.translations import pgettext_tip as tip_
|
||||
|
||||
|
||||
def osl_compile(input_path, report):
|
||||
"""compile .osl file with given filepath to temporary .oso file"""
|
||||
|
@ -103,7 +105,7 @@ def update_script_node(node, report):
|
|||
ok = _cycles.osl_update_node(data, node.id_data.as_pointer(), node.as_pointer(), oso_path)
|
||||
|
||||
if not ok:
|
||||
report({'ERROR'}, "OSL query failed to open " + oso_path)
|
||||
report({'ERROR'}, tip_("OSL query failed to open %s") % oso_path)
|
||||
else:
|
||||
report({'ERROR'}, "OSL script compilation failed, see console for errors")
|
||||
|
||||
|
|
|
@ -1335,7 +1335,7 @@ static void ghost_wayland_log_handler(const char *msg, va_list arg)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_GHOST_X11
|
||||
#if defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
/**
|
||||
* Check if the system is running X11.
|
||||
* This is not intended to be a fool-proof check (the `DISPLAY` is not validated for e.g.).
|
||||
|
@ -1349,7 +1349,7 @@ static bool ghost_wayland_is_x11_available()
|
|||
}
|
||||
return false;
|
||||
}
|
||||
#endif /* WITH_GHOST_X11 */
|
||||
#endif /* WITH_GHOST_X11 && WITH_GHOST_WAYLAND_LIBDECOR */
|
||||
|
||||
static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
|
||||
{
|
||||
|
|
|
@ -3667,7 +3667,8 @@ def km_grease_pencil_stroke_edit_mode(params):
|
|||
("gpencil.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
# Extrude and move selected points
|
||||
op_tool_optional(
|
||||
("gpencil.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
|
||||
("gpencil.extrude_move", {"type": 'E', "value": 'PRESS'},
|
||||
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
|
||||
(op_tool_cycle, "builtin.extrude"), params),
|
||||
# Delete
|
||||
op_menu("VIEW3D_MT_edit_gpencil_delete", {"type": 'X', "value": 'PRESS'}),
|
||||
|
@ -4656,8 +4657,10 @@ def km_object_mode(params):
|
|||
op_menu("VIEW3D_MT_add", {"type": 'A', "value": 'PRESS', "shift": True}),
|
||||
op_menu("VIEW3D_MT_object_apply", {"type": 'A', "value": 'PRESS', "ctrl": True}),
|
||||
op_menu("VIEW3D_MT_make_links", {"type": 'L', "value": 'PRESS', "ctrl": True}),
|
||||
("object.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
("object.duplicate_move_linked", {"type": 'D', "value": 'PRESS', "alt": True}, None),
|
||||
("object.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
|
||||
("object.duplicate_move_linked", {"type": 'D', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
|
||||
("object.join", {"type": 'J', "value": 'PRESS', "ctrl": True}, None),
|
||||
("wm.context_toggle", {"type": 'PERIOD', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("data_path", 'tool_settings.use_transform_data_origin')]}),
|
||||
|
@ -4762,7 +4765,8 @@ def km_curve(params):
|
|||
("curve.separate", {"type": 'P', "value": 'PRESS'}, None),
|
||||
("curve.split", {"type": 'Y', "value": 'PRESS'}, None),
|
||||
op_tool_optional(
|
||||
("curve.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
|
||||
("curve.extrude_move", {"type": 'E', "value": 'PRESS'},
|
||||
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
|
||||
(op_tool_cycle, "builtin.extrude"), params),
|
||||
("curve.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
("curve.make_segment", {"type": 'F', "value": 'PRESS'}, None),
|
||||
|
@ -5371,7 +5375,8 @@ def km_mesh(params):
|
|||
("mesh.normals_make_consistent", {"type": 'N', "value": 'PRESS', "shift": True, "ctrl": True},
|
||||
{"properties": [("inside", True)]}),
|
||||
op_tool_optional(
|
||||
("view3d.edit_mesh_extrude_move_normal", {"type": 'E', "value": 'PRESS'}, None),
|
||||
("view3d.edit_mesh_extrude_move_normal", {"type": 'E', "value": 'PRESS'},
|
||||
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
|
||||
(op_tool_cycle, "builtin.extrude_region"), params),
|
||||
op_menu("VIEW3D_MT_edit_mesh_extrude", {"type": 'E', "value": 'PRESS', "alt": True}),
|
||||
("transform.edge_crease", {"type": 'E', "value": 'PRESS', "shift": True}, None),
|
||||
|
@ -5388,11 +5393,13 @@ def km_mesh(params):
|
|||
# No tool is available for this.
|
||||
("mesh.rip_move", {"type": 'V', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("MESH_OT_rip", [("use_fill", True)],)]}),
|
||||
("mesh.rip_edge_move", {"type": 'D', "value": 'PRESS', "alt": True}, None),
|
||||
("mesh.rip_edge_move", {"type": 'D', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
|
||||
op_menu("VIEW3D_MT_edit_mesh_merge", {"type": 'M', "value": 'PRESS'}),
|
||||
op_menu("VIEW3D_MT_edit_mesh_split", {"type": 'M', "value": 'PRESS', "alt": True}),
|
||||
("mesh.edge_face_add", {"type": 'F', "value": 'PRESS', "repeat": True}, None),
|
||||
("mesh.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
("mesh.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
|
||||
op_menu("VIEW3D_MT_mesh_add", {"type": 'A', "value": 'PRESS', "shift": True}),
|
||||
("mesh.separate", {"type": 'P', "value": 'PRESS'}, None),
|
||||
("mesh.split", {"type": 'Y', "value": 'PRESS'}, None),
|
||||
|
@ -5510,7 +5517,8 @@ def km_armature(params):
|
|||
("armature.dissolve", {"type": 'X', "value": 'PRESS', "ctrl": True}, None),
|
||||
("armature.dissolve", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, None),
|
||||
op_tool_optional(
|
||||
("armature.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
|
||||
("armature.extrude_move", {"type": 'E', "value": 'PRESS'},
|
||||
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
|
||||
(op_tool_cycle, "builtin.extrude"), params),
|
||||
("armature.extrude_forked", {"type": 'E', "value": 'PRESS', "shift": True}, None),
|
||||
("armature.click_extrude", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, None),
|
||||
|
|
|
@ -90,7 +90,7 @@ class NodeAddOperator:
|
|||
except AttributeError as e:
|
||||
self.report(
|
||||
{'ERROR_INVALID_INPUT'},
|
||||
"Node has no attribute " + setting.name)
|
||||
tip_("Node has no attribute %s") % setting.name)
|
||||
print(str(e))
|
||||
# Continue despite invalid attribute
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
|
|||
bl_label = "Extrude Individual and Move"
|
||||
bl_idname = "view3d.edit_mesh_extrude_individual_move"
|
||||
|
||||
allow_navigation: BoolProperty(
|
||||
name="allow_navigation",
|
||||
default=False,
|
||||
description="Allow navigation",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
obj = context.active_object
|
||||
|
@ -32,14 +38,29 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
|
|||
TRANSFORM_OT_translate={
|
||||
"orient_type": 'NORMAL',
|
||||
"constraint_axis": (False, False, True),
|
||||
"allow_navigation": self.allow_navigation,
|
||||
},
|
||||
)
|
||||
elif select_mode[2] and totface > 1:
|
||||
bpy.ops.mesh.extrude_faces_move('INVOKE_REGION_WIN')
|
||||
bpy.ops.mesh.extrude_faces_move(
|
||||
'INVOKE_REGION_WIN',
|
||||
TRANSFORM_OT_shrink_fatten={
|
||||
"allow_navigation": self.allow_navigation,
|
||||
})
|
||||
elif select_mode[1] and totedge >= 1:
|
||||
bpy.ops.mesh.extrude_edges_move('INVOKE_REGION_WIN')
|
||||
bpy.ops.mesh.extrude_edges_move(
|
||||
'INVOKE_REGION_WIN',
|
||||
TRANSFORM_OT_translate={
|
||||
"allow_navigation": self.allow_navigation,
|
||||
},
|
||||
)
|
||||
else:
|
||||
bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN')
|
||||
bpy.ops.mesh.extrude_vertices_move(
|
||||
'INVOKE_REGION_WIN',
|
||||
TRANSFORM_OT_translate={
|
||||
"allow_navigation": self.allow_navigation,
|
||||
},
|
||||
)
|
||||
|
||||
# ignore return from operators above because they are 'RUNNING_MODAL',
|
||||
# and cause this one not to be freed. #24671.
|
||||
|
@ -60,13 +81,19 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
description="Dissolves adjacent faces and intersects new geometry",
|
||||
)
|
||||
|
||||
allow_navigation: BoolProperty(
|
||||
name="allow_navigation",
|
||||
default=False,
|
||||
description="Allow navigation",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
obj = context.active_object
|
||||
return (obj is not None and obj.mode == 'EDIT')
|
||||
|
||||
@staticmethod
|
||||
def extrude_region(context, use_vert_normals, dissolve_and_intersect):
|
||||
def extrude_region(context, use_vert_normals, dissolve_and_intersect, allow_navigation):
|
||||
mesh = context.object.data
|
||||
|
||||
totface = mesh.total_face_sel
|
||||
|
@ -77,7 +104,9 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
if use_vert_normals:
|
||||
bpy.ops.mesh.extrude_region_shrink_fatten(
|
||||
'INVOKE_REGION_WIN',
|
||||
TRANSFORM_OT_shrink_fatten={},
|
||||
TRANSFORM_OT_shrink_fatten={
|
||||
"allow_navigation": allow_navigation,
|
||||
},
|
||||
)
|
||||
elif dissolve_and_intersect:
|
||||
bpy.ops.mesh.extrude_manifold(
|
||||
|
@ -88,6 +117,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
TRANSFORM_OT_translate={
|
||||
"orient_type": 'NORMAL',
|
||||
"constraint_axis": (False, False, True),
|
||||
"allow_navigation": allow_navigation,
|
||||
},
|
||||
)
|
||||
else:
|
||||
|
@ -96,6 +126,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
TRANSFORM_OT_translate={
|
||||
"orient_type": 'NORMAL',
|
||||
"constraint_axis": (False, False, True),
|
||||
"allow_navigation": allow_navigation,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -109,16 +140,23 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
# Not a popular choice, too restrictive for retopo.
|
||||
# "constraint_axis": (True, True, False)})
|
||||
"constraint_axis": (False, False, False),
|
||||
"allow_navigation": allow_navigation,
|
||||
})
|
||||
else:
|
||||
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
|
||||
bpy.ops.mesh.extrude_region_move(
|
||||
'INVOKE_REGION_WIN',
|
||||
TRANSFORM_OT_translate={
|
||||
"allow_navigation": allow_navigation,
|
||||
},
|
||||
)
|
||||
|
||||
# ignore return from operators above because they are 'RUNNING_MODAL',
|
||||
# and cause this one not to be freed. #24671.
|
||||
return {'FINISHED'}
|
||||
|
||||
def execute(self, context):
|
||||
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False, self.dissolve_and_intersect)
|
||||
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(
|
||||
context, False, self.dissolve_and_intersect, self.allow_navigation)
|
||||
|
||||
def invoke(self, context, _event):
|
||||
return self.execute(context)
|
||||
|
@ -129,13 +167,19 @@ class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator):
|
|||
bl_label = "Extrude and Move on Individual Normals"
|
||||
bl_idname = "view3d.edit_mesh_extrude_move_shrink_fatten"
|
||||
|
||||
allow_navigation: BoolProperty(
|
||||
name="allow_navigation",
|
||||
default=False,
|
||||
description="Allow navigation",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
obj = context.active_object
|
||||
return (obj is not None and obj.mode == 'EDIT')
|
||||
|
||||
def execute(self, context):
|
||||
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True, False)
|
||||
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True, False, self.allow_navigation)
|
||||
|
||||
def invoke(self, context, _event):
|
||||
return self.execute(context)
|
||||
|
@ -146,6 +190,12 @@ class VIEW3D_OT_edit_mesh_extrude_manifold_normal(Operator):
|
|||
bl_label = "Extrude Manifold Along Normals"
|
||||
bl_idname = "view3d.edit_mesh_extrude_manifold_normal"
|
||||
|
||||
allow_navigation: BoolProperty(
|
||||
name="allow_navigation",
|
||||
default=False,
|
||||
description="Allow navigation",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
obj = context.active_object
|
||||
|
@ -160,6 +210,7 @@ class VIEW3D_OT_edit_mesh_extrude_manifold_normal(Operator):
|
|||
TRANSFORM_OT_translate={
|
||||
"orient_type": 'NORMAL',
|
||||
"constraint_axis": (False, False, True),
|
||||
"allow_navigation": self.allow_navigation,
|
||||
},
|
||||
)
|
||||
return {'FINISHED'}
|
||||
|
|
|
@ -1043,17 +1043,9 @@ class VIEW3D_MT_transform_base:
|
|||
"use_transform_navigation",
|
||||
False)
|
||||
|
||||
props = layout.operator("transform.translate")
|
||||
props.release_confirm = False
|
||||
props.allow_navigation = allow_navigation
|
||||
|
||||
props = layout.operator("transform.rotate")
|
||||
props.release_confirm = False
|
||||
props.allow_navigation = allow_navigation
|
||||
|
||||
props = layout.operator("transform.resize", text="Scale")
|
||||
props.release_confirm = False
|
||||
props.allow_navigation = allow_navigation
|
||||
layout.operator("transform.translate").allow_navigation = allow_navigation
|
||||
layout.operator("transform.rotate").allow_navigation = allow_navigation
|
||||
layout.operator("transform.resize", text="Scale").allow_navigation = allow_navigation
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1073,21 +1065,30 @@ class VIEW3D_MT_transform_base:
|
|||
# Generic transform menu - geometry types
|
||||
class VIEW3D_MT_transform(VIEW3D_MT_transform_base, Menu):
|
||||
def draw(self, context):
|
||||
allow_navigation = getattr(
|
||||
context.window_manager.keyconfigs.active.preferences,
|
||||
"use_transform_navigation",
|
||||
False)
|
||||
|
||||
# base menu
|
||||
VIEW3D_MT_transform_base.draw(self, context)
|
||||
|
||||
# generic...
|
||||
layout = self.layout
|
||||
if context.mode == 'EDIT_MESH':
|
||||
layout.operator("transform.shrink_fatten", text="Shrink/Fatten")
|
||||
layout.operator("transform.shrink_fatten", text="Shrink/Fatten").allow_navigation = allow_navigation
|
||||
layout.operator("transform.skin_resize")
|
||||
elif context.mode == 'EDIT_CURVE':
|
||||
layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
|
||||
|
||||
if context.mode != 'EDIT_CURVES':
|
||||
layout.separator()
|
||||
layout.operator("transform.translate", text="Move Texture Space").texture_space = True
|
||||
layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
|
||||
props = layout.operator("transform.translate", text="Move Texture Space")
|
||||
props.texture_space = True
|
||||
props.allow_navigation = allow_navigation
|
||||
props = layout.operator("transform.resize", text="Scale Texture Space")
|
||||
props.texture_space = True
|
||||
props.allow_navigation = allow_navigation
|
||||
|
||||
|
||||
# Object-specific extensions to Transform menu
|
||||
|
@ -4172,6 +4173,11 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
|
|||
col.operator("mesh.delete", text="Delete Edges").type = 'EDGE'
|
||||
|
||||
if is_face_mode:
|
||||
allow_navigation = getattr(
|
||||
context.window_manager.keyconfigs.active.preferences,
|
||||
"use_transform_navigation",
|
||||
False)
|
||||
|
||||
col = row.column(align=True)
|
||||
|
||||
col.label(text="Face Context Menu", icon='FACESEL')
|
||||
|
@ -4182,9 +4188,12 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
|
|||
|
||||
col.separator()
|
||||
|
||||
col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces")
|
||||
col.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals")
|
||||
col.operator("mesh.extrude_faces_move", text="Extrude Individual Faces")
|
||||
col.operator("view3d.edit_mesh_extrude_move_normal",
|
||||
text="Extrude Faces").allow_navigation = allow_navigation
|
||||
col.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
|
||||
text="Extrude Faces Along Normals").allow_navigation = allow_navigation
|
||||
col.operator("mesh.extrude_faces_move",
|
||||
text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.allow_navigation = allow_navigation
|
||||
|
||||
col.operator("mesh.inset")
|
||||
col.operator("mesh.poke")
|
||||
|
@ -4233,46 +4242,39 @@ class VIEW3D_MT_edit_mesh_select_mode(Menu):
|
|||
class VIEW3D_MT_edit_mesh_extrude(Menu):
|
||||
bl_label = "Extrude"
|
||||
|
||||
_extrude_funcs = {
|
||||
'VERT': lambda layout:
|
||||
layout.operator("mesh.extrude_vertices_move", text="Extrude Vertices"),
|
||||
'EDGE': lambda layout:
|
||||
layout.operator("mesh.extrude_edges_move", text="Extrude Edges"),
|
||||
'REGION': lambda layout:
|
||||
layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces"),
|
||||
'REGION_VERT_NORMAL': lambda layout:
|
||||
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals"),
|
||||
'FACE': lambda layout:
|
||||
layout.operator("mesh.extrude_faces_move", text="Extrude Individual Faces"),
|
||||
'MANIFOLD': lambda layout:
|
||||
layout.operator("view3d.edit_mesh_extrude_manifold_normal", text="Extrude Manifold"),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def extrude_options(context):
|
||||
tool_settings = context.tool_settings
|
||||
select_mode = tool_settings.mesh_select_mode
|
||||
mesh = context.object.data
|
||||
|
||||
menu = []
|
||||
if mesh.total_face_sel:
|
||||
menu += ['REGION', 'REGION_VERT_NORMAL', 'FACE', 'MANIFOLD']
|
||||
if mesh.total_edge_sel and (select_mode[0] or select_mode[1]):
|
||||
menu += ['EDGE']
|
||||
if mesh.total_vert_sel and select_mode[0]:
|
||||
menu += ['VERT']
|
||||
|
||||
# should never get here
|
||||
return menu
|
||||
|
||||
def draw(self, context):
|
||||
from math import pi
|
||||
|
||||
allow_navigation = getattr(
|
||||
context.window_manager.keyconfigs.active.preferences,
|
||||
"use_transform_navigation",
|
||||
False)
|
||||
|
||||
layout = self.layout
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
||||
for menu_id in self.extrude_options(context):
|
||||
self._extrude_funcs[menu_id](layout)
|
||||
tool_settings = context.tool_settings
|
||||
select_mode = tool_settings.mesh_select_mode
|
||||
mesh = context.object.data
|
||||
|
||||
if mesh.total_face_sel:
|
||||
layout.operator("view3d.edit_mesh_extrude_move_normal",
|
||||
text="Extrude Faces").allow_navigation = allow_navigation
|
||||
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
|
||||
text="Extrude Faces Along Normals").allow_navigation = allow_navigation
|
||||
layout.operator(
|
||||
"mesh.extrude_faces_move",
|
||||
text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.allow_navigation = allow_navigation
|
||||
layout.operator("view3d.edit_mesh_extrude_manifold_normal",
|
||||
text="Extrude Manifold").allow_navigation = allow_navigation
|
||||
|
||||
if mesh.total_edge_sel and (select_mode[0] or select_mode[1]):
|
||||
layout.operator("mesh.extrude_edges_move",
|
||||
text="Extrude Edges").TRANSFORM_OT_translate.allow_navigation = allow_navigation
|
||||
|
||||
if mesh.total_vert_sel and select_mode[0]:
|
||||
layout.operator("mesh.extrude_vertices_move",
|
||||
text="Extrude Vertices").TRANSFORM_OT_translate.allow_navigation = allow_navigation
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -4424,14 +4426,23 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
|
|||
bl_label = "Face"
|
||||
bl_idname = "VIEW3D_MT_edit_mesh_faces"
|
||||
|
||||
def draw(self, _context):
|
||||
def draw(self, context):
|
||||
allow_navigation = getattr(
|
||||
context.window_manager.keyconfigs.active.preferences,
|
||||
"use_transform_navigation",
|
||||
False)
|
||||
|
||||
layout = self.layout
|
||||
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
||||
layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces")
|
||||
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals")
|
||||
layout.operator("mesh.extrude_faces_move", text="Extrude Individual Faces")
|
||||
layout.operator("view3d.edit_mesh_extrude_move_normal",
|
||||
text="Extrude Faces").allow_navigation = allow_navigation
|
||||
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
|
||||
text="Extrude Faces Along Normals").allow_navigation = allow_navigation
|
||||
layout.operator(
|
||||
"mesh.extrude_faces_move",
|
||||
text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.allow_navigation = allow_navigation
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
|
|
@ -58,6 +58,11 @@ struct AnimData *BKE_animdata_ensure_id(struct ID *id);
|
|||
*/
|
||||
bool BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct bAction *act);
|
||||
|
||||
/**
|
||||
* Same as BKE_animdata_set_action(), except sets `tmpact` instead of `action`.
|
||||
*/
|
||||
bool BKE_animdata_set_tmpact(struct ReportList *reports, struct ID *id, struct bAction *act);
|
||||
|
||||
bool BKE_animdata_action_editable(const struct AnimData *adt);
|
||||
|
||||
/**
|
||||
|
|
|
@ -114,39 +114,23 @@ AnimData *BKE_animdata_ensure_id(ID *id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Action Setter --------------------------------------- */
|
||||
|
||||
bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
|
||||
/* Action / Tmpact Setter shared code -------------------------
|
||||
*
|
||||
* Both the action and tmpact setter functions have essentially
|
||||
* identical semantics, because tmpact is just a place to temporarily
|
||||
* store the main action during tweaking. This function contains the
|
||||
* shared code between those two setter functions, setting the action
|
||||
* of the passed `act_slot` to `act`.
|
||||
*
|
||||
* Preconditions:
|
||||
* - `id` and `act_slot` must be non-null (but the pointer `act_slot`
|
||||
* points to can be null).
|
||||
* - `id` must have animation data.
|
||||
* - `act_slot` must be a pointer to either the `action` or `tmpact`
|
||||
* field of `id`'s animation data.
|
||||
*/
|
||||
static bool animdata_set_action(ReportList *reports, ID *id, bAction **act_slot, bAction *act)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
|
||||
/* Animdata validity check. */
|
||||
if (adt == NULL) {
|
||||
BKE_report(reports, RPT_WARNING, "No AnimData to set action on");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (adt->action == act) {
|
||||
/* Don't bother reducing and increasing the user count when there is nothing changing. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!BKE_animdata_action_editable(adt)) {
|
||||
/* Cannot remove, otherwise things turn to custard. */
|
||||
BKE_report(reports, RPT_ERROR, "Cannot change action, as it is still being edited in NLA");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Unassign current action. */
|
||||
if (adt->action) {
|
||||
id_us_min((ID *)adt->action);
|
||||
adt->action = NULL;
|
||||
}
|
||||
|
||||
if (act == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Action must have same type as owner. */
|
||||
if (!BKE_animdata_action_ensure_idroot(id, act)) {
|
||||
/* Cannot set to this type. */
|
||||
|
@ -160,12 +144,59 @@ bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
|
|||
return false;
|
||||
}
|
||||
|
||||
adt->action = act;
|
||||
id_us_plus((ID *)adt->action);
|
||||
if (*act_slot == act) {
|
||||
/* Don't bother reducing and increasing the user count when there is nothing changing. */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Unassign current action. */
|
||||
if (*act_slot) {
|
||||
id_us_min((ID *)*act_slot);
|
||||
*act_slot = NULL;
|
||||
}
|
||||
|
||||
if (act == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*act_slot = act;
|
||||
id_us_plus((ID *)*act_slot);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Tmpact Setter --------------------------------------- */
|
||||
bool BKE_animdata_set_tmpact(ReportList *reports, ID *id, bAction *act)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
|
||||
if (adt == NULL) {
|
||||
BKE_report(reports, RPT_WARNING, "No AnimData to set tmpact on");
|
||||
return false;
|
||||
}
|
||||
|
||||
return animdata_set_action(reports, id, &adt->tmpact, act);
|
||||
}
|
||||
|
||||
/* Action Setter --------------------------------------- */
|
||||
bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
|
||||
if (adt == NULL) {
|
||||
BKE_report(reports, RPT_WARNING, "No AnimData to set action on");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!BKE_animdata_action_editable(adt)) {
|
||||
/* Cannot remove, otherwise things turn to custard. */
|
||||
BKE_report(reports, RPT_ERROR, "Cannot change action, as it is still being edited in NLA");
|
||||
return false;
|
||||
}
|
||||
|
||||
return animdata_set_action(reports, id, &adt->action, act);
|
||||
}
|
||||
|
||||
bool BKE_animdata_action_editable(const AnimData *adt)
|
||||
{
|
||||
/* Active action is only editable when it is not a tweaking strip. */
|
||||
|
|
|
@ -386,7 +386,7 @@ UndoStep *BKE_undosys_stack_init_or_active_with_type(UndoStack *ustack, const Un
|
|||
void BKE_undosys_stack_limit_steps_and_memory(UndoStack *ustack, int steps, size_t memory_limit)
|
||||
{
|
||||
UNDO_NESTED_ASSERT(false);
|
||||
if ((steps == -1) && (memory_limit != 0)) {
|
||||
if ((steps == -1) && (memory_limit == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -400,6 +400,12 @@ void BKE_undosys_stack_limit_steps_and_memory(UndoStack *ustack, int steps, size
|
|||
if (memory_limit) {
|
||||
data_size_all += us->data_size;
|
||||
if (data_size_all > memory_limit) {
|
||||
CLOG_INFO(&LOG,
|
||||
1,
|
||||
"At step %zu: data_size_all=%zu >= memory_limit=%zu",
|
||||
us_count,
|
||||
data_size_all,
|
||||
memory_limit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -413,6 +419,8 @@ void BKE_undosys_stack_limit_steps_and_memory(UndoStack *ustack, int steps, size
|
|||
}
|
||||
}
|
||||
|
||||
CLOG_INFO(&LOG, 1, "Total steps %zu: data_size_all=%zu", us_count, data_size_all);
|
||||
|
||||
if (us) {
|
||||
#ifdef WITH_GLOBAL_UNDO_KEEP_ONE
|
||||
/* Hack, we need to keep at least one BKE_UNDOSYS_TYPE_MEMFILE. */
|
||||
|
|
|
@ -246,7 +246,7 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
|
|||
|
||||
/* WORKAROUND: Needed because node_tree isn't present in test shaders. */
|
||||
if (pipeline_type == MAT_PIPE_DEFERRED) {
|
||||
info.define("MAT_RENDER_PASS_SUPPORT");
|
||||
info.additional_info("eevee_render_pass_out");
|
||||
}
|
||||
|
||||
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) {
|
||||
|
|
|
@ -107,7 +107,8 @@ GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
|
|||
.additional_info("eevee_camera",
|
||||
"eevee_utility_texture",
|
||||
"eevee_sampling_data",
|
||||
"eevee_render_pass_out",
|
||||
/* Added at runtime because of test shaders not having `node_tree`. */
|
||||
// "eevee_render_pass_out",
|
||||
"eevee_cryptomatte_out");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surf_forward)
|
||||
|
|
|
@ -991,42 +991,44 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
|
|||
|
||||
static void flip_names(tAnimCopybufItem *aci, char **r_name)
|
||||
{
|
||||
if (aci->is_bone) {
|
||||
int ofs_start;
|
||||
int ofs_end;
|
||||
|
||||
if (BLI_str_quoted_substr_range(aci->rna_path, "pose.bones[", &ofs_start, &ofs_end)) {
|
||||
char *str_start = aci->rna_path + ofs_start;
|
||||
const char *str_end = aci->rna_path + ofs_end;
|
||||
|
||||
/* Swap out the name.
|
||||
* Note that there is no need to un-escape the string to flip it. */
|
||||
char bname_new[MAX_VGROUP_NAME];
|
||||
char *str_iter;
|
||||
int length, prefix_l, postfix_l;
|
||||
|
||||
prefix_l = str_start - aci->rna_path;
|
||||
|
||||
length = str_end - str_start;
|
||||
postfix_l = strlen(str_end);
|
||||
|
||||
/* Temporary substitute with NULL terminator. */
|
||||
BLI_assert(str_start[length] == '\"');
|
||||
str_start[length] = 0;
|
||||
BLI_string_flip_side_name(bname_new, str_start, false, sizeof(bname_new));
|
||||
str_start[length] = '\"';
|
||||
|
||||
str_iter = *r_name = MEM_mallocN(sizeof(char) * (prefix_l + postfix_l + length + 1),
|
||||
"flipped_path");
|
||||
|
||||
BLI_strncpy(str_iter, aci->rna_path, prefix_l + 1);
|
||||
str_iter += prefix_l;
|
||||
BLI_strncpy(str_iter, bname_new, length + 1);
|
||||
str_iter += length;
|
||||
BLI_strncpy(str_iter, str_end, postfix_l + 1);
|
||||
str_iter[postfix_l] = '\0';
|
||||
}
|
||||
if (!aci->is_bone) {
|
||||
return;
|
||||
}
|
||||
int ofs_start, ofs_end;
|
||||
if (!BLI_str_quoted_substr_range(aci->rna_path, "pose.bones[", &ofs_start, &ofs_end)) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *str_start = aci->rna_path + ofs_start;
|
||||
const char *str_end = aci->rna_path + ofs_end;
|
||||
|
||||
/* Swap out the name.
|
||||
* NOTE: there is no need to un-escape the string to flip it.
|
||||
* However the buffer does need to be twice the size. */
|
||||
char bname_new[MAX_VGROUP_NAME * 2];
|
||||
char *str_iter;
|
||||
int len_old, prefix_l, postfix_l;
|
||||
|
||||
prefix_l = str_start - aci->rna_path;
|
||||
|
||||
len_old = str_end - str_start;
|
||||
postfix_l = strlen(str_end);
|
||||
|
||||
/* Temporary substitute with NULL terminator. */
|
||||
BLI_assert(str_start[len_old] == '\"');
|
||||
str_start[len_old] = 0;
|
||||
const int len_new = BLI_string_flip_side_name(bname_new, str_start, false, sizeof(bname_new));
|
||||
str_start[len_old] = '\"';
|
||||
|
||||
str_iter = *r_name = MEM_mallocN(sizeof(char) * (prefix_l + postfix_l + len_new + 1),
|
||||
"flipped_path");
|
||||
|
||||
memcpy(str_iter, aci->rna_path, prefix_l);
|
||||
str_iter += prefix_l;
|
||||
memcpy(str_iter, bname_new, len_new);
|
||||
str_iter += len_new;
|
||||
memcpy(str_iter, str_end, postfix_l);
|
||||
str_iter[postfix_l] = '\0';
|
||||
}
|
||||
|
||||
/* ------------------- */
|
||||
|
|
|
@ -398,26 +398,30 @@ static void init_indexer_entry_from_value(FileIndexerEntry &indexer_entry,
|
|||
|
||||
if (entry.has_description()) {
|
||||
const StringRefNull description = entry.get_description();
|
||||
char *description_c_str = static_cast<char *>(MEM_mallocN(description.size() + 1, __func__));
|
||||
BLI_strncpy(description_c_str, description.c_str(), description.size() + 1);
|
||||
const size_t c_str_size = description.size() + 1;
|
||||
char *description_c_str = static_cast<char *>(MEM_mallocN(c_str_size, __func__));
|
||||
memcpy(description_c_str, description.c_str(), c_str_size);
|
||||
asset_data->description = description_c_str;
|
||||
}
|
||||
if (entry.has_author()) {
|
||||
const StringRefNull author = entry.get_author();
|
||||
char *author_c_str = static_cast<char *>(MEM_mallocN(author.size() + 1, __func__));
|
||||
BLI_strncpy(author_c_str, author.c_str(), author.size() + 1);
|
||||
const size_t c_str_size = author.size() + 1;
|
||||
char *author_c_str = static_cast<char *>(MEM_mallocN(c_str_size, __func__));
|
||||
memcpy(author_c_str, author.c_str(), c_str_size);
|
||||
asset_data->author = author_c_str;
|
||||
}
|
||||
if (entry.has_copyright()) {
|
||||
const StringRefNull copyright = entry.get_copyright();
|
||||
char *copyright_c_str = static_cast<char *>(MEM_mallocN(copyright.size() + 1, __func__));
|
||||
BLI_strncpy(copyright_c_str, copyright.c_str(), copyright.size() + 1);
|
||||
const size_t c_str_size = copyright.size() + 1;
|
||||
char *copyright_c_str = static_cast<char *>(MEM_mallocN(c_str_size, __func__));
|
||||
memcpy(copyright_c_str, copyright.c_str(), c_str_size);
|
||||
asset_data->copyright = copyright_c_str;
|
||||
}
|
||||
if (entry.has_license()) {
|
||||
const StringRefNull license = entry.get_license();
|
||||
char *license_c_str = static_cast<char *>(MEM_mallocN(license.size() + 1, __func__));
|
||||
BLI_strncpy(license_c_str, license.c_str(), license.size() + 1);
|
||||
const size_t c_str_size = license.size() + 1;
|
||||
char *license_c_str = static_cast<char *>(MEM_mallocN(c_str_size, __func__));
|
||||
memcpy(license_c_str, license.c_str(), c_str_size);
|
||||
asset_data->license = license_c_str;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,13 +34,13 @@ struct uiViewHandle;
|
|||
struct uiViewItemHandle;
|
||||
struct wmDrag;
|
||||
|
||||
void UI_but_func_pushed_state_set(uiBut *but, std::function<bool(const uiBut &)> func);
|
||||
|
||||
namespace blender::ui {
|
||||
|
||||
class AbstractGridView;
|
||||
class AbstractTreeView;
|
||||
|
||||
void UI_but_func_pushed_state_set(uiBut *but, std::function<bool(const uiBut &)> func);
|
||||
|
||||
/**
|
||||
* An item in a breadcrumb-like context. Currently this struct is very simple, but more
|
||||
* could be added to it in the future, to support interactivity or tooltips, for example.
|
||||
|
|
|
@ -3339,7 +3339,9 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in
|
|||
char *buf = static_cast<char *>(
|
||||
MEM_mallocN(sizeof(char) * (sellen + 1), "ui_textedit_copypaste"));
|
||||
|
||||
BLI_strncpy(buf, data->str + but->selsta, sellen + 1);
|
||||
memcpy(buf, data->str + but->selsta, sellen);
|
||||
buf[sellen] = '\0';
|
||||
|
||||
WM_clipboard_text_set(buf, false);
|
||||
MEM_freeN(buf);
|
||||
|
||||
|
|
|
@ -151,9 +151,9 @@ static void grease_pencil_stroke_cancel(bContext *C, wmOperator *op)
|
|||
|
||||
static void GREASE_PENCIL_OT_brush_stroke(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Stroke Curves Sculpt";
|
||||
ot->name = "Grease Pencil Draw";
|
||||
ot->idname = "GREASE_PENCIL_OT_brush_stroke";
|
||||
ot->description = "Sculpt curves using a brush";
|
||||
ot->description = "Draw a new stroke in the active Grease Pencil object";
|
||||
|
||||
ot->invoke = grease_pencil_stroke_invoke;
|
||||
ot->modal = grease_pencil_stroke_modal;
|
||||
|
|
|
@ -6628,9 +6628,12 @@ static void default_paint_slot_color_get(int layer_type, Material *ma, float col
|
|||
case LAYER_ROUGHNESS:
|
||||
case LAYER_METALLIC: {
|
||||
bNodeTree *ntree = nullptr;
|
||||
ma->nodetree->ensure_topology_cache();
|
||||
const blender::Span<bNode *> nodes = ma->nodetree->nodes_by_type("ShaderNodeBsdfPrincipled");
|
||||
bNode *in_node = nodes.is_empty() ? nullptr : nodes.first();
|
||||
bNode *in_node = nullptr;
|
||||
if (ma && ma->nodetree) {
|
||||
ma->nodetree->ensure_topology_cache();
|
||||
const blender::Span<bNode *> nodes = ma->nodetree->nodes_by_type("ShaderNodeBsdfPrincipled");
|
||||
in_node = nodes.is_empty() ? nullptr : nodes.first();
|
||||
}
|
||||
if (!in_node) {
|
||||
/* An existing material or Principled BSDF node could not be found.
|
||||
* Copy default color values from a default Principled BSDF instead. */
|
||||
|
@ -6861,7 +6864,8 @@ static int texture_paint_add_texture_paint_slot_invoke(bContext *C,
|
|||
get_default_texture_layer_name_for_object(ob, type, (char *)&imagename, sizeof(imagename));
|
||||
RNA_string_set(op->ptr, "name", imagename);
|
||||
|
||||
/* Set default color. Copy the color from nodes, so it matches the existing material. */
|
||||
/* Set default color. Copy the color from nodes, so it matches the existing material.
|
||||
* Material could be null so we should have a default color. */
|
||||
float color[4];
|
||||
default_paint_slot_color_get(type, ma, color);
|
||||
RNA_float_set_array(op->ptr, "color", color);
|
||||
|
|
|
@ -37,18 +37,6 @@
|
|||
|
||||
#include "console_intern.h"
|
||||
|
||||
/* TODO: Text operations not yet supported for console:
|
||||
* Mac KM_OSKEY-arrow to beginning/end of line
|
||||
* Mac KM_OSKEY-backspace to start of line
|
||||
* Mac KM_OSKEY-delete to end of line
|
||||
* Text cursor insertion by mouse
|
||||
* Mouse drag to select does not change text cursor position.
|
||||
* Shift-ctrl-arrow to select word
|
||||
* ctrl-x to copy to clipboard and delete.
|
||||
* ctrl-a to select all
|
||||
* ctrl-z,shift-crtrl-z undo/redo
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utilities
|
||||
* \{ */
|
||||
|
|
|
@ -1299,7 +1299,7 @@ static void std_node_socket_draw(
|
|||
}
|
||||
|
||||
if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_HIDE_VALUE) ||
|
||||
((sock->flag & SOCK_IS_LINKED) && !(sock->link->is_muted())))
|
||||
((sock->flag & SOCK_IS_LINKED) && !all_links_muted(*sock)))
|
||||
{
|
||||
node_socket_button_label(C, layout, ptr, node_ptr, text);
|
||||
return;
|
||||
|
|
|
@ -294,6 +294,7 @@ void NODE_OT_group_edit(wmOperatorType *ot);
|
|||
/* node_relationships.cc */
|
||||
|
||||
void update_multi_input_indices_for_removed_links(bNode &node);
|
||||
bool all_links_muted(const bNodeSocket &socket);
|
||||
|
||||
void NODE_OT_link(wmOperatorType *ot);
|
||||
void NODE_OT_link_make(wmOperatorType *ot);
|
||||
|
|
|
@ -1588,7 +1588,7 @@ void NODE_OT_links_cut(wmOperatorType *ot)
|
|||
/** \name Mute Links Operator
|
||||
* \{ */
|
||||
|
||||
static bool all_links_muted(const bNodeSocket &socket)
|
||||
bool all_links_muted(const bNodeSocket &socket)
|
||||
{
|
||||
for (const bNodeLink *link : socket.directly_linked_links()) {
|
||||
if (!(link->flag & NODE_LINK_MUTED)) {
|
||||
|
|
|
@ -2152,7 +2152,7 @@ static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEv
|
|||
}
|
||||
|
||||
DynStr *dyn_str = BLI_dynstr_new();
|
||||
BLI_dynstr_appendf(dyn_str, "Purging %d unused data-blocks (", num_tagged[INDEX_ID_NULL]);
|
||||
BLI_dynstr_appendf(dyn_str, TIP_("Purging %d unused data-blocks ("), num_tagged[INDEX_ID_NULL]);
|
||||
bool is_first = true;
|
||||
for (int i = 0; i < INDEX_ID_MAX - 2; i++) {
|
||||
if (num_tagged[i] != 0) {
|
||||
|
|
|
@ -658,7 +658,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
|||
t->flag |= T_NO_CURSOR_WRAP;
|
||||
}
|
||||
|
||||
if (op && (t->flag & T_MODAL) && !(t->flag & T_RELEASE_CONFIRM) &&
|
||||
if (op && (t->flag & T_MODAL) &&
|
||||
(prop = RNA_struct_find_property(op->ptr, "allow_navigation")) &&
|
||||
RNA_property_boolean_get(op->ptr, prop))
|
||||
{
|
||||
|
|
|
@ -1091,7 +1091,7 @@ static void TRANSFORM_OT_shrink_fatten(wmOperatorType *ot)
|
|||
|
||||
WM_operatortype_props_advanced_begin(ot);
|
||||
|
||||
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
|
||||
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_VIEW3D_NAVIGATION);
|
||||
}
|
||||
|
||||
static void TRANSFORM_OT_tosphere(wmOperatorType *ot)
|
||||
|
|
|
@ -121,7 +121,7 @@ void outputNumInput(NumInput *n, char *str, UnitSettings *unit_settings)
|
|||
#endif
|
||||
|
||||
if (n->val_flag[i] & NUM_INVALID) {
|
||||
STRNCPY(val, "Invalid");
|
||||
STRNCPY(val, TIP_("Invalid"));
|
||||
}
|
||||
else {
|
||||
BKE_unit_value_as_string_adaptive(val,
|
||||
|
|
|
@ -1,422 +1,422 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BLI_dynstr.h"
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "vk_backend.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_debug.hh"
|
||||
|
||||
static CLG_LogRef LOG = {"gpu.debug.vulkan"};
|
||||
|
||||
namespace blender::gpu {
|
||||
void VKContext::debug_group_begin(const char *name, int)
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
debug::push_marker(device, name);
|
||||
}
|
||||
|
||||
void VKContext::debug_group_end()
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
debug::pop_marker(device);
|
||||
}
|
||||
|
||||
bool VKContext::debug_capture_begin()
|
||||
{
|
||||
return VKBackend::get().debug_capture_begin();
|
||||
}
|
||||
|
||||
bool VKBackend::debug_capture_begin()
|
||||
{
|
||||
#ifdef WITH_RENDERDOC
|
||||
return renderdoc_api_.start_frame_capture(device_get().instance_get(), nullptr);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void VKContext::debug_capture_end()
|
||||
{
|
||||
VKBackend::get().debug_capture_end();
|
||||
}
|
||||
|
||||
void VKBackend::debug_capture_end()
|
||||
{
|
||||
#ifdef WITH_RENDERDOC
|
||||
renderdoc_api_.end_frame_capture(device_get().instance_get(), nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *VKContext::debug_capture_scope_create(const char * /*name*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool VKContext::debug_capture_scope_begin(void * /*scope*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void VKContext::debug_capture_scope_end(void * /*scope*/) {}
|
||||
} // namespace blender::gpu
|
||||
|
||||
namespace blender::gpu::debug {
|
||||
|
||||
void VKDebuggingTools::init(VkInstance vk_instance)
|
||||
{
|
||||
PFN_vkGetInstanceProcAddr instance_proc_addr = vkGetInstanceProcAddr;
|
||||
enabled = false;
|
||||
vk_debug_utils_messenger = nullptr;
|
||||
vkCmdBeginDebugUtilsLabelEXT_r = (PFN_vkCmdBeginDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkCmdBeginDebugUtilsLabelEXT");
|
||||
vkCmdEndDebugUtilsLabelEXT_r = (PFN_vkCmdEndDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkCmdEndDebugUtilsLabelEXT");
|
||||
vkCmdInsertDebugUtilsLabelEXT_r = (PFN_vkCmdInsertDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkCmdInsertDebugUtilsLabelEXT");
|
||||
vkCreateDebugUtilsMessengerEXT_r = (PFN_vkCreateDebugUtilsMessengerEXT)instance_proc_addr(
|
||||
vk_instance, "vkCreateDebugUtilsMessengerEXT");
|
||||
vkDestroyDebugUtilsMessengerEXT_r = (PFN_vkDestroyDebugUtilsMessengerEXT)instance_proc_addr(
|
||||
vk_instance, "vkDestroyDebugUtilsMessengerEXT");
|
||||
vkQueueBeginDebugUtilsLabelEXT_r = (PFN_vkQueueBeginDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkQueueBeginDebugUtilsLabelEXT");
|
||||
vkQueueEndDebugUtilsLabelEXT_r = (PFN_vkQueueEndDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkQueueEndDebugUtilsLabelEXT");
|
||||
vkQueueInsertDebugUtilsLabelEXT_r = (PFN_vkQueueInsertDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkQueueInsertDebugUtilsLabelEXT");
|
||||
vkSetDebugUtilsObjectNameEXT_r = (PFN_vkSetDebugUtilsObjectNameEXT)instance_proc_addr(
|
||||
vk_instance, "vkSetDebugUtilsObjectNameEXT");
|
||||
vkSetDebugUtilsObjectTagEXT_r = (PFN_vkSetDebugUtilsObjectTagEXT)instance_proc_addr(
|
||||
vk_instance, "vkSetDebugUtilsObjectTagEXT");
|
||||
vkSubmitDebugUtilsMessageEXT_r = (PFN_vkSubmitDebugUtilsMessageEXT)instance_proc_addr(
|
||||
vk_instance, "vkSubmitDebugUtilsMessageEXT");
|
||||
if (vkCmdBeginDebugUtilsLabelEXT_r) {
|
||||
enabled = true;
|
||||
init_messenger(vk_instance);
|
||||
}
|
||||
}
|
||||
|
||||
void VKDebuggingTools::deinit(VkInstance vk_instance)
|
||||
{
|
||||
if (enabled) {
|
||||
destroy_messenger(vk_instance);
|
||||
}
|
||||
vkCmdBeginDebugUtilsLabelEXT_r = nullptr;
|
||||
vkCmdEndDebugUtilsLabelEXT_r = nullptr;
|
||||
vkCmdInsertDebugUtilsLabelEXT_r = nullptr;
|
||||
vkCreateDebugUtilsMessengerEXT_r = nullptr;
|
||||
vkDestroyDebugUtilsMessengerEXT_r = nullptr;
|
||||
vkQueueBeginDebugUtilsLabelEXT_r = nullptr;
|
||||
vkQueueEndDebugUtilsLabelEXT_r = nullptr;
|
||||
vkQueueInsertDebugUtilsLabelEXT_r = nullptr;
|
||||
vkSetDebugUtilsObjectNameEXT_r = nullptr;
|
||||
vkSetDebugUtilsObjectTagEXT_r = nullptr;
|
||||
vkSubmitDebugUtilsMessageEXT_r = nullptr;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
void object_label(VkObjectType vk_object_type, uint64_t object_handle, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
VkDebugUtilsObjectNameInfoEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
|
||||
info.objectType = vk_object_type;
|
||||
info.objectHandle = object_handle;
|
||||
info.pObjectName = name;
|
||||
debugging_tools.vkSetDebugUtilsObjectNameEXT_r(device.device_get(), &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void push_marker(VkCommandBuffer vk_command_buffer, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
VkDebugUtilsLabelEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
info.pLabelName = name;
|
||||
debugging_tools.vkCmdBeginDebugUtilsLabelEXT_r(vk_command_buffer, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_marker(VkCommandBuffer vk_command_buffer, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
VkDebugUtilsLabelEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
info.pLabelName = name;
|
||||
debugging_tools.vkCmdInsertDebugUtilsLabelEXT_r(vk_command_buffer, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pop_marker(VkCommandBuffer vk_command_buffer)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
debugging_tools.vkCmdEndDebugUtilsLabelEXT_r(vk_command_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void push_marker(const VKDevice &device, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
VkDebugUtilsLabelEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
info.pLabelName = name;
|
||||
debugging_tools.vkQueueBeginDebugUtilsLabelEXT_r(device.queue_get(), &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_marker(const VKDevice &device, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
VkDebugUtilsLabelEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
info.pLabelName = name;
|
||||
debugging_tools.vkQueueInsertDebugUtilsLabelEXT_r(device.queue_get(), &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pop_marker(const VKDevice &device)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
debugging_tools.vkQueueEndDebugUtilsLabelEXT_r(device.queue_get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::gpu::debug
|
||||
|
||||
namespace blender::gpu::debug {
|
||||
VKDebuggingTools::~VKDebuggingTools()
|
||||
{
|
||||
BLI_assert(vk_debug_utils_messenger == nullptr);
|
||||
};
|
||||
|
||||
void VKDebuggingTools::print_labels(const VkDebugUtilsMessengerCallbackDataEXT *callback_data)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (uint32_t object = 0; object < callback_data->objectCount; ++object) {
|
||||
ss << " - ObjectType[" << to_string(callback_data->pObjects[object].objectType) << "],";
|
||||
ss << "Handle[0x" << std::hex
|
||||
<< static_cast<uintptr_t>(callback_data->pObjects[object].objectHandle) << "]";
|
||||
if (callback_data->pObjects[object].pObjectName) {
|
||||
ss << ",Name[" << callback_data->pObjects[object].pObjectName << "]";
|
||||
}
|
||||
ss << std::endl;
|
||||
}
|
||||
for (uint32_t label = 0; label < callback_data->cmdBufLabelCount; ++label) {
|
||||
if (callback_data->pCmdBufLabels[label].pLabelName) {
|
||||
ss << " - CommandBuffer : " << callback_data->pCmdBufLabels[label].pLabelName << std::endl;
|
||||
}
|
||||
}
|
||||
for (uint32_t label = 0; label < callback_data->queueLabelCount; ++label) {
|
||||
if (callback_data->pQueueLabels[label].pLabelName) {
|
||||
ss << " - Queue : " << callback_data->pQueueLabels[label].pLabelName << std::endl;
|
||||
}
|
||||
}
|
||||
ss << std::endl;
|
||||
printf("%s", ss.str().c_str());
|
||||
}
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT /* message_type*/,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
|
||||
void *user_data);
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT /* message_type*/,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
|
||||
void *user_data)
|
||||
{
|
||||
VKDebuggingTools &debugging_tools = *reinterpret_cast<VKDebuggingTools *>(user_data);
|
||||
if (debugging_tools.is_ignore(callback_data->messageIdNumber)) {
|
||||
return VK_FALSE;
|
||||
}
|
||||
bool use_color = CLG_color_support_get(&LOG);
|
||||
UNUSED_VARS(use_color);
|
||||
bool enabled = false;
|
||||
if ((message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) ||
|
||||
(message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT))
|
||||
{
|
||||
if ((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= CLG_SEVERITY_INFO)) {
|
||||
const char *format = "{0x%x}% s\n %s ";
|
||||
CLG_logf(LOG.type,
|
||||
CLG_SEVERITY_INFO,
|
||||
"",
|
||||
"",
|
||||
format,
|
||||
callback_data->messageIdNumber,
|
||||
callback_data->pMessageIdName,
|
||||
callback_data->pMessage);
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CLG_Severity clog_severity;
|
||||
switch (message_severity) {
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
|
||||
clog_severity = CLG_SEVERITY_WARN;
|
||||
break;
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
||||
clog_severity = CLG_SEVERITY_ERROR;
|
||||
break;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
enabled = true;
|
||||
if (clog_severity == CLG_SEVERITY_ERROR) {
|
||||
const char *format = " %s {0x%x}\n %s ";
|
||||
CLG_logf(LOG.type,
|
||||
clog_severity,
|
||||
"",
|
||||
"",
|
||||
format,
|
||||
callback_data->pMessageIdName,
|
||||
callback_data->messageIdNumber,
|
||||
callback_data->pMessage);
|
||||
}
|
||||
else if (LOG.type->level >= CLG_SEVERITY_WARN) {
|
||||
const char *format = " %s {0x%x}\n %s ";
|
||||
CLG_logf(LOG.type,
|
||||
clog_severity,
|
||||
"",
|
||||
"",
|
||||
format,
|
||||
callback_data->pMessageIdName,
|
||||
callback_data->messageIdNumber,
|
||||
callback_data->pMessage);
|
||||
}
|
||||
}
|
||||
if ((enabled) && ((callback_data->objectCount > 0) || (callback_data->cmdBufLabelCount > 0) ||
|
||||
(callback_data->queueLabelCount > 0)))
|
||||
{
|
||||
debugging_tools.print_labels(callback_data);
|
||||
}
|
||||
return VK_FALSE;
|
||||
};
|
||||
|
||||
VkResult VKDebuggingTools::init_messenger(VkInstance vk_instance)
|
||||
{
|
||||
vk_message_id_number_ignored.clear();
|
||||
BLI_assert(enabled);
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT create_info;
|
||||
create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
create_info.pNext = nullptr;
|
||||
create_info.flags = 0;
|
||||
create_info.messageSeverity = message_severity;
|
||||
create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
create_info.pfnUserCallback = messenger_callback;
|
||||
create_info.pUserData = this;
|
||||
VkResult res = vkCreateDebugUtilsMessengerEXT_r(
|
||||
vk_instance, &create_info, nullptr, &vk_debug_utils_messenger);
|
||||
BLI_assert(res == VK_SUCCESS);
|
||||
return res;
|
||||
}
|
||||
|
||||
void VKDebuggingTools::destroy_messenger(VkInstance vk_instance)
|
||||
{
|
||||
if (vk_debug_utils_messenger == nullptr) {
|
||||
return;
|
||||
}
|
||||
BLI_assert(enabled);
|
||||
vkDestroyDebugUtilsMessengerEXT_r(vk_instance, vk_debug_utils_messenger, nullptr);
|
||||
|
||||
vk_message_id_number_ignored.clear();
|
||||
vk_debug_utils_messenger = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
bool VKDebuggingTools::is_ignore(int32_t id_number)
|
||||
{
|
||||
bool found = false;
|
||||
{
|
||||
std::scoped_lock lock(ignore_mutex);
|
||||
found = vk_message_id_number_ignored.contains(id_number);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void VKDebuggingTools::add_group(int32_t id_number)
|
||||
{
|
||||
std::scoped_lock lock(ignore_mutex);
|
||||
vk_message_id_number_ignored.add(id_number);
|
||||
};
|
||||
|
||||
void VKDebuggingTools::remove_group(int32_t id_number)
|
||||
{
|
||||
std::scoped_lock lock(ignore_mutex);
|
||||
vk_message_id_number_ignored.remove(id_number);
|
||||
};
|
||||
|
||||
void raise_message(int32_t id_number,
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT vk_severity_flag_bits,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
DynStr *ds = nullptr;
|
||||
va_list arg;
|
||||
char *info = nullptr;
|
||||
|
||||
va_start(arg, format);
|
||||
|
||||
ds = BLI_dynstr_new();
|
||||
BLI_dynstr_vappendf(ds, format, arg);
|
||||
info = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
||||
va_end(arg);
|
||||
|
||||
static VkDebugUtilsMessengerCallbackDataEXT vk_call_back_data;
|
||||
vk_call_back_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
|
||||
vk_call_back_data.pNext = VK_NULL_HANDLE;
|
||||
vk_call_back_data.messageIdNumber = id_number;
|
||||
vk_call_back_data.pMessageIdName = "VulkanMessenger";
|
||||
vk_call_back_data.objectCount = 0;
|
||||
vk_call_back_data.flags = 0;
|
||||
vk_call_back_data.pObjects = VK_NULL_HANDLE;
|
||||
vk_call_back_data.pMessage = info;
|
||||
debugging_tools.vkSubmitDebugUtilsMessageEXT_r(device.instance_get(),
|
||||
vk_severity_flag_bits,
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
|
||||
&vk_call_back_data);
|
||||
MEM_freeN((void *)info);
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace blender::gpu::debug
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Foundation.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BLI_dynstr.h"
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "vk_backend.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_debug.hh"
|
||||
|
||||
static CLG_LogRef LOG = {"gpu.debug.vulkan"};
|
||||
|
||||
namespace blender::gpu {
|
||||
void VKContext::debug_group_begin(const char *name, int)
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
debug::push_marker(device, name);
|
||||
}
|
||||
|
||||
void VKContext::debug_group_end()
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
debug::pop_marker(device);
|
||||
}
|
||||
|
||||
bool VKContext::debug_capture_begin()
|
||||
{
|
||||
return VKBackend::get().debug_capture_begin();
|
||||
}
|
||||
|
||||
bool VKBackend::debug_capture_begin()
|
||||
{
|
||||
#ifdef WITH_RENDERDOC
|
||||
return renderdoc_api_.start_frame_capture(device_get().instance_get(), nullptr);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void VKContext::debug_capture_end()
|
||||
{
|
||||
VKBackend::get().debug_capture_end();
|
||||
}
|
||||
|
||||
void VKBackend::debug_capture_end()
|
||||
{
|
||||
#ifdef WITH_RENDERDOC
|
||||
renderdoc_api_.end_frame_capture(device_get().instance_get(), nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *VKContext::debug_capture_scope_create(const char * /*name*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool VKContext::debug_capture_scope_begin(void * /*scope*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void VKContext::debug_capture_scope_end(void * /*scope*/) {}
|
||||
} // namespace blender::gpu
|
||||
|
||||
namespace blender::gpu::debug {
|
||||
|
||||
void VKDebuggingTools::init(VkInstance vk_instance)
|
||||
{
|
||||
PFN_vkGetInstanceProcAddr instance_proc_addr = vkGetInstanceProcAddr;
|
||||
enabled = false;
|
||||
vk_debug_utils_messenger = nullptr;
|
||||
vkCmdBeginDebugUtilsLabelEXT_r = (PFN_vkCmdBeginDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkCmdBeginDebugUtilsLabelEXT");
|
||||
vkCmdEndDebugUtilsLabelEXT_r = (PFN_vkCmdEndDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkCmdEndDebugUtilsLabelEXT");
|
||||
vkCmdInsertDebugUtilsLabelEXT_r = (PFN_vkCmdInsertDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkCmdInsertDebugUtilsLabelEXT");
|
||||
vkCreateDebugUtilsMessengerEXT_r = (PFN_vkCreateDebugUtilsMessengerEXT)instance_proc_addr(
|
||||
vk_instance, "vkCreateDebugUtilsMessengerEXT");
|
||||
vkDestroyDebugUtilsMessengerEXT_r = (PFN_vkDestroyDebugUtilsMessengerEXT)instance_proc_addr(
|
||||
vk_instance, "vkDestroyDebugUtilsMessengerEXT");
|
||||
vkQueueBeginDebugUtilsLabelEXT_r = (PFN_vkQueueBeginDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkQueueBeginDebugUtilsLabelEXT");
|
||||
vkQueueEndDebugUtilsLabelEXT_r = (PFN_vkQueueEndDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkQueueEndDebugUtilsLabelEXT");
|
||||
vkQueueInsertDebugUtilsLabelEXT_r = (PFN_vkQueueInsertDebugUtilsLabelEXT)instance_proc_addr(
|
||||
vk_instance, "vkQueueInsertDebugUtilsLabelEXT");
|
||||
vkSetDebugUtilsObjectNameEXT_r = (PFN_vkSetDebugUtilsObjectNameEXT)instance_proc_addr(
|
||||
vk_instance, "vkSetDebugUtilsObjectNameEXT");
|
||||
vkSetDebugUtilsObjectTagEXT_r = (PFN_vkSetDebugUtilsObjectTagEXT)instance_proc_addr(
|
||||
vk_instance, "vkSetDebugUtilsObjectTagEXT");
|
||||
vkSubmitDebugUtilsMessageEXT_r = (PFN_vkSubmitDebugUtilsMessageEXT)instance_proc_addr(
|
||||
vk_instance, "vkSubmitDebugUtilsMessageEXT");
|
||||
if (vkCmdBeginDebugUtilsLabelEXT_r) {
|
||||
enabled = true;
|
||||
init_messenger(vk_instance);
|
||||
}
|
||||
}
|
||||
|
||||
void VKDebuggingTools::deinit(VkInstance vk_instance)
|
||||
{
|
||||
if (enabled) {
|
||||
destroy_messenger(vk_instance);
|
||||
}
|
||||
vkCmdBeginDebugUtilsLabelEXT_r = nullptr;
|
||||
vkCmdEndDebugUtilsLabelEXT_r = nullptr;
|
||||
vkCmdInsertDebugUtilsLabelEXT_r = nullptr;
|
||||
vkCreateDebugUtilsMessengerEXT_r = nullptr;
|
||||
vkDestroyDebugUtilsMessengerEXT_r = nullptr;
|
||||
vkQueueBeginDebugUtilsLabelEXT_r = nullptr;
|
||||
vkQueueEndDebugUtilsLabelEXT_r = nullptr;
|
||||
vkQueueInsertDebugUtilsLabelEXT_r = nullptr;
|
||||
vkSetDebugUtilsObjectNameEXT_r = nullptr;
|
||||
vkSetDebugUtilsObjectTagEXT_r = nullptr;
|
||||
vkSubmitDebugUtilsMessageEXT_r = nullptr;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
void object_label(VkObjectType vk_object_type, uint64_t object_handle, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
VkDebugUtilsObjectNameInfoEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
|
||||
info.objectType = vk_object_type;
|
||||
info.objectHandle = object_handle;
|
||||
info.pObjectName = name;
|
||||
debugging_tools.vkSetDebugUtilsObjectNameEXT_r(device.device_get(), &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void push_marker(VkCommandBuffer vk_command_buffer, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
VkDebugUtilsLabelEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
info.pLabelName = name;
|
||||
debugging_tools.vkCmdBeginDebugUtilsLabelEXT_r(vk_command_buffer, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_marker(VkCommandBuffer vk_command_buffer, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
VkDebugUtilsLabelEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
info.pLabelName = name;
|
||||
debugging_tools.vkCmdInsertDebugUtilsLabelEXT_r(vk_command_buffer, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pop_marker(VkCommandBuffer vk_command_buffer)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
debugging_tools.vkCmdEndDebugUtilsLabelEXT_r(vk_command_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void push_marker(const VKDevice &device, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
VkDebugUtilsLabelEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
info.pLabelName = name;
|
||||
debugging_tools.vkQueueBeginDebugUtilsLabelEXT_r(device.queue_get(), &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_marker(const VKDevice &device, const char *name)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
VkDebugUtilsLabelEXT info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
info.pLabelName = name;
|
||||
debugging_tools.vkQueueInsertDebugUtilsLabelEXT_r(device.queue_get(), &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pop_marker(const VKDevice &device)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
debugging_tools.vkQueueEndDebugUtilsLabelEXT_r(device.queue_get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::gpu::debug
|
||||
|
||||
namespace blender::gpu::debug {
|
||||
VKDebuggingTools::~VKDebuggingTools()
|
||||
{
|
||||
BLI_assert(vk_debug_utils_messenger == nullptr);
|
||||
};
|
||||
|
||||
void VKDebuggingTools::print_labels(const VkDebugUtilsMessengerCallbackDataEXT *callback_data)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (uint32_t object = 0; object < callback_data->objectCount; ++object) {
|
||||
ss << " - ObjectType[" << to_string(callback_data->pObjects[object].objectType) << "],";
|
||||
ss << "Handle[0x" << std::hex
|
||||
<< static_cast<uintptr_t>(callback_data->pObjects[object].objectHandle) << "]";
|
||||
if (callback_data->pObjects[object].pObjectName) {
|
||||
ss << ",Name[" << callback_data->pObjects[object].pObjectName << "]";
|
||||
}
|
||||
ss << std::endl;
|
||||
}
|
||||
for (uint32_t label = 0; label < callback_data->cmdBufLabelCount; ++label) {
|
||||
if (callback_data->pCmdBufLabels[label].pLabelName) {
|
||||
ss << " - CommandBuffer : " << callback_data->pCmdBufLabels[label].pLabelName << std::endl;
|
||||
}
|
||||
}
|
||||
for (uint32_t label = 0; label < callback_data->queueLabelCount; ++label) {
|
||||
if (callback_data->pQueueLabels[label].pLabelName) {
|
||||
ss << " - Queue : " << callback_data->pQueueLabels[label].pLabelName << std::endl;
|
||||
}
|
||||
}
|
||||
ss << std::endl;
|
||||
printf("%s", ss.str().c_str());
|
||||
}
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT /* message_type*/,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
|
||||
void *user_data);
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT /* message_type*/,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
|
||||
void *user_data)
|
||||
{
|
||||
VKDebuggingTools &debugging_tools = *reinterpret_cast<VKDebuggingTools *>(user_data);
|
||||
if (debugging_tools.is_ignore(callback_data->messageIdNumber)) {
|
||||
return VK_FALSE;
|
||||
}
|
||||
bool use_color = CLG_color_support_get(&LOG);
|
||||
UNUSED_VARS(use_color);
|
||||
bool enabled = false;
|
||||
if ((message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) ||
|
||||
(message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT))
|
||||
{
|
||||
if ((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= CLG_SEVERITY_INFO)) {
|
||||
const char *format = "{0x%x}% s\n %s ";
|
||||
CLG_logf(LOG.type,
|
||||
CLG_SEVERITY_INFO,
|
||||
"",
|
||||
"",
|
||||
format,
|
||||
callback_data->messageIdNumber,
|
||||
callback_data->pMessageIdName,
|
||||
callback_data->pMessage);
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CLG_Severity clog_severity;
|
||||
switch (message_severity) {
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
|
||||
clog_severity = CLG_SEVERITY_WARN;
|
||||
break;
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
||||
clog_severity = CLG_SEVERITY_ERROR;
|
||||
break;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
enabled = true;
|
||||
if (clog_severity == CLG_SEVERITY_ERROR) {
|
||||
const char *format = " %s {0x%x}\n %s ";
|
||||
CLG_logf(LOG.type,
|
||||
clog_severity,
|
||||
"",
|
||||
"",
|
||||
format,
|
||||
callback_data->pMessageIdName,
|
||||
callback_data->messageIdNumber,
|
||||
callback_data->pMessage);
|
||||
}
|
||||
else if (LOG.type->level >= CLG_SEVERITY_WARN) {
|
||||
const char *format = " %s {0x%x}\n %s ";
|
||||
CLG_logf(LOG.type,
|
||||
clog_severity,
|
||||
"",
|
||||
"",
|
||||
format,
|
||||
callback_data->pMessageIdName,
|
||||
callback_data->messageIdNumber,
|
||||
callback_data->pMessage);
|
||||
}
|
||||
}
|
||||
if ((enabled) && ((callback_data->objectCount > 0) || (callback_data->cmdBufLabelCount > 0) ||
|
||||
(callback_data->queueLabelCount > 0)))
|
||||
{
|
||||
debugging_tools.print_labels(callback_data);
|
||||
}
|
||||
return VK_FALSE;
|
||||
};
|
||||
|
||||
VkResult VKDebuggingTools::init_messenger(VkInstance vk_instance)
|
||||
{
|
||||
vk_message_id_number_ignored.clear();
|
||||
BLI_assert(enabled);
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT create_info;
|
||||
create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
create_info.pNext = nullptr;
|
||||
create_info.flags = 0;
|
||||
create_info.messageSeverity = message_severity;
|
||||
create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
create_info.pfnUserCallback = messenger_callback;
|
||||
create_info.pUserData = this;
|
||||
VkResult res = vkCreateDebugUtilsMessengerEXT_r(
|
||||
vk_instance, &create_info, nullptr, &vk_debug_utils_messenger);
|
||||
BLI_assert(res == VK_SUCCESS);
|
||||
return res;
|
||||
}
|
||||
|
||||
void VKDebuggingTools::destroy_messenger(VkInstance vk_instance)
|
||||
{
|
||||
if (vk_debug_utils_messenger == nullptr) {
|
||||
return;
|
||||
}
|
||||
BLI_assert(enabled);
|
||||
vkDestroyDebugUtilsMessengerEXT_r(vk_instance, vk_debug_utils_messenger, nullptr);
|
||||
|
||||
vk_message_id_number_ignored.clear();
|
||||
vk_debug_utils_messenger = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
bool VKDebuggingTools::is_ignore(int32_t id_number)
|
||||
{
|
||||
bool found = false;
|
||||
{
|
||||
std::scoped_lock lock(ignore_mutex);
|
||||
found = vk_message_id_number_ignored.contains(id_number);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void VKDebuggingTools::add_group(int32_t id_number)
|
||||
{
|
||||
std::scoped_lock lock(ignore_mutex);
|
||||
vk_message_id_number_ignored.add(id_number);
|
||||
};
|
||||
|
||||
void VKDebuggingTools::remove_group(int32_t id_number)
|
||||
{
|
||||
std::scoped_lock lock(ignore_mutex);
|
||||
vk_message_id_number_ignored.remove(id_number);
|
||||
};
|
||||
|
||||
void raise_message(int32_t id_number,
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT vk_severity_flag_bits,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKDebuggingTools &debugging_tools = device.debugging_tools_get();
|
||||
if (debugging_tools.enabled) {
|
||||
DynStr *ds = nullptr;
|
||||
va_list arg;
|
||||
char *info = nullptr;
|
||||
|
||||
va_start(arg, format);
|
||||
|
||||
ds = BLI_dynstr_new();
|
||||
BLI_dynstr_vappendf(ds, format, arg);
|
||||
info = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
||||
va_end(arg);
|
||||
|
||||
static VkDebugUtilsMessengerCallbackDataEXT vk_call_back_data;
|
||||
vk_call_back_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
|
||||
vk_call_back_data.pNext = VK_NULL_HANDLE;
|
||||
vk_call_back_data.messageIdNumber = id_number;
|
||||
vk_call_back_data.pMessageIdName = "VulkanMessenger";
|
||||
vk_call_back_data.objectCount = 0;
|
||||
vk_call_back_data.flags = 0;
|
||||
vk_call_back_data.pObjects = VK_NULL_HANDLE;
|
||||
vk_call_back_data.pMessage = info;
|
||||
debugging_tools.vkSubmitDebugUtilsMessageEXT_r(device.instance_get(),
|
||||
vk_severity_flag_bits,
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
|
||||
&vk_call_back_data);
|
||||
MEM_freeN((void *)info);
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace blender::gpu::debug
|
||||
|
|
|
@ -1,88 +1,88 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "vk_common.hh"
|
||||
|
||||
#include <mutex>
|
||||
#include <typeindex>
|
||||
|
||||
namespace blender::gpu {
|
||||
class VKContext;
|
||||
class VKDevice;
|
||||
|
||||
namespace debug {
|
||||
class VKDebuggingTools {
|
||||
public:
|
||||
bool enabled = false;
|
||||
VkDebugUtilsMessageSeverityFlagsEXT message_severity =
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
/* Function pointer definitions. */
|
||||
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT_r = nullptr;
|
||||
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT_r = nullptr;
|
||||
PFN_vkSubmitDebugUtilsMessageEXT vkSubmitDebugUtilsMessageEXT_r = nullptr;
|
||||
PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkQueueBeginDebugUtilsLabelEXT vkQueueBeginDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkQueueEndDebugUtilsLabelEXT vkQueueEndDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkQueueInsertDebugUtilsLabelEXT vkQueueInsertDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT_r = nullptr;
|
||||
PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT_r = nullptr;
|
||||
VKDebuggingTools() = default;
|
||||
~VKDebuggingTools();
|
||||
void init(VkInstance vk_instance);
|
||||
void deinit(VkInstance vk_instance);
|
||||
bool is_ignore(int32_t id_number);
|
||||
VkResult init_messenger(VkInstance vk_instance);
|
||||
void destroy_messenger(VkInstance vk_instance);
|
||||
void print_labels(const VkDebugUtilsMessengerCallbackDataEXT *callback_data);
|
||||
|
||||
private:
|
||||
VkDebugUtilsMessengerEXT vk_debug_utils_messenger = nullptr;
|
||||
Set<int32_t> vk_message_id_number_ignored;
|
||||
std::mutex ignore_mutex;
|
||||
void add_group(int32_t id_number);
|
||||
void remove_group(int32_t id_number);
|
||||
};
|
||||
|
||||
void object_label(VkObjectType vk_object_type, uint64_t object_handle, const char *name);
|
||||
template<typename T> void object_label(T vk_object_type, const char *name)
|
||||
{
|
||||
if (!(G.debug & G_DEBUG_GPU)) {
|
||||
return;
|
||||
}
|
||||
const size_t label_size = 64;
|
||||
char label[label_size];
|
||||
memset(label, 0, label_size);
|
||||
static int stats = 0;
|
||||
SNPRINTF(label, "%s_%d", name, stats++);
|
||||
object_label(to_vk_object_type(vk_object_type), (uint64_t)vk_object_type, (const char *)label);
|
||||
};
|
||||
|
||||
void push_marker(VkCommandBuffer vk_command_buffer, const char *name);
|
||||
void set_marker(VkCommandBuffer vk_command_buffer, const char *name);
|
||||
void pop_marker(VkCommandBuffer vk_command_buffer);
|
||||
void push_marker(const VKDevice &device, const char *name);
|
||||
void set_marker(const VKDevice &device, const char *name);
|
||||
void pop_marker(const VKDevice &device);
|
||||
/* how to use : debug::raise_message(0xB41ca2,VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,"This
|
||||
* is a raise message. %llx", (uintptr_t)vk_object); */
|
||||
void raise_message(int32_t id_number,
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT vk_severity_flag_bits,
|
||||
const char *fmt,
|
||||
...);
|
||||
} // namespace debug
|
||||
} // namespace blender::gpu
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Foundation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "vk_common.hh"
|
||||
|
||||
#include <mutex>
|
||||
#include <typeindex>
|
||||
|
||||
namespace blender::gpu {
|
||||
class VKContext;
|
||||
class VKDevice;
|
||||
|
||||
namespace debug {
|
||||
class VKDebuggingTools {
|
||||
public:
|
||||
bool enabled = false;
|
||||
VkDebugUtilsMessageSeverityFlagsEXT message_severity =
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
/* Function pointer definitions. */
|
||||
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT_r = nullptr;
|
||||
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT_r = nullptr;
|
||||
PFN_vkSubmitDebugUtilsMessageEXT vkSubmitDebugUtilsMessageEXT_r = nullptr;
|
||||
PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkQueueBeginDebugUtilsLabelEXT vkQueueBeginDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkQueueEndDebugUtilsLabelEXT vkQueueEndDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkQueueInsertDebugUtilsLabelEXT vkQueueInsertDebugUtilsLabelEXT_r = nullptr;
|
||||
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT_r = nullptr;
|
||||
PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT_r = nullptr;
|
||||
VKDebuggingTools() = default;
|
||||
~VKDebuggingTools();
|
||||
void init(VkInstance vk_instance);
|
||||
void deinit(VkInstance vk_instance);
|
||||
bool is_ignore(int32_t id_number);
|
||||
VkResult init_messenger(VkInstance vk_instance);
|
||||
void destroy_messenger(VkInstance vk_instance);
|
||||
void print_labels(const VkDebugUtilsMessengerCallbackDataEXT *callback_data);
|
||||
|
||||
private:
|
||||
VkDebugUtilsMessengerEXT vk_debug_utils_messenger = nullptr;
|
||||
Set<int32_t> vk_message_id_number_ignored;
|
||||
std::mutex ignore_mutex;
|
||||
void add_group(int32_t id_number);
|
||||
void remove_group(int32_t id_number);
|
||||
};
|
||||
|
||||
void object_label(VkObjectType vk_object_type, uint64_t object_handle, const char *name);
|
||||
template<typename T> void object_label(T vk_object_type, const char *name)
|
||||
{
|
||||
if (!(G.debug & G_DEBUG_GPU)) {
|
||||
return;
|
||||
}
|
||||
const size_t label_size = 64;
|
||||
char label[label_size];
|
||||
memset(label, 0, label_size);
|
||||
static int stats = 0;
|
||||
SNPRINTF(label, "%s_%d", name, stats++);
|
||||
object_label(to_vk_object_type(vk_object_type), (uint64_t)vk_object_type, (const char *)label);
|
||||
};
|
||||
|
||||
void push_marker(VkCommandBuffer vk_command_buffer, const char *name);
|
||||
void set_marker(VkCommandBuffer vk_command_buffer, const char *name);
|
||||
void pop_marker(VkCommandBuffer vk_command_buffer);
|
||||
void push_marker(const VKDevice &device, const char *name);
|
||||
void set_marker(const VKDevice &device, const char *name);
|
||||
void pop_marker(const VKDevice &device);
|
||||
/* how to use : debug::raise_message(0xB41ca2,VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,"This
|
||||
* is a raise message. %llx", (uintptr_t)vk_object); */
|
||||
void raise_message(int32_t id_number,
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT vk_severity_flag_bits,
|
||||
const char *fmt,
|
||||
...);
|
||||
} // namespace debug
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -8,6 +8,7 @@ set(INC
|
|||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../blentranslation
|
||||
../../bmesh
|
||||
../../depsgraph
|
||||
../../editors/include
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
using Alembic::AbcGeom::CameraSample;
|
||||
using Alembic::AbcGeom::ICamera;
|
||||
using Alembic::AbcGeom::ICompoundProperty;
|
||||
|
@ -47,14 +49,14 @@ bool AbcCameraReader::accepts_object_type(
|
|||
const char **err_str) const
|
||||
{
|
||||
if (!Alembic::AbcGeom::ICamera::matches(alembic_header)) {
|
||||
*err_str =
|
||||
*err_str = N_(
|
||||
"Object type mismatch, Alembic object path pointed to Camera when importing, but not any "
|
||||
"more.";
|
||||
"more.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->type != OB_CAMERA) {
|
||||
*err_str = "Object type mismatch, Alembic object path points to Camera.";
|
||||
*err_str = N_("Object type mismatch, Alembic object path points to Camera.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_object.h"
|
||||
|
@ -61,14 +63,14 @@ bool AbcCurveReader::accepts_object_type(
|
|||
const char **err_str) const
|
||||
{
|
||||
if (!Alembic::AbcGeom::ICurves::matches(alembic_header)) {
|
||||
*err_str =
|
||||
*err_str = N_(
|
||||
"Object type mismatch, Alembic object path pointed to Curves when importing, but not any "
|
||||
"more.";
|
||||
"more.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->type != OB_CURVES_LEGACY) {
|
||||
*err_str = "Object type mismatch, Alembic object path points to Curves.";
|
||||
*err_str = N_("Object type mismatch, Alembic object path points to Curves.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_geom.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
|
@ -634,14 +636,14 @@ bool AbcMeshReader::accepts_object_type(
|
|||
const char **err_str) const
|
||||
{
|
||||
if (!Alembic::AbcGeom::IPolyMesh::matches(alembic_header)) {
|
||||
*err_str =
|
||||
*err_str = N_(
|
||||
"Object type mismatch, Alembic object path pointed to PolyMesh when importing, but not "
|
||||
"any more.";
|
||||
"any more.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->type != OB_MESH) {
|
||||
*err_str = "Object type mismatch, Alembic object path points to PolyMesh.";
|
||||
*err_str = N_("Object type mismatch, Alembic object path points to PolyMesh.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -971,14 +973,14 @@ bool AbcSubDReader::accepts_object_type(
|
|||
const char **err_str) const
|
||||
{
|
||||
if (!Alembic::AbcGeom::ISubD::matches(alembic_header)) {
|
||||
*err_str =
|
||||
*err_str = N_(
|
||||
"Object type mismatch, Alembic object path pointed to SubD when importing, but not any "
|
||||
"more.";
|
||||
"more.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->type != OB_MESH) {
|
||||
*err_str = "Object type mismatch, Alembic object path points to SubD.";
|
||||
*err_str = N_("Object type mismatch, Alembic object path points to SubD.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
|
@ -65,14 +67,14 @@ bool AbcNurbsReader::accepts_object_type(
|
|||
const char **err_str) const
|
||||
{
|
||||
if (!Alembic::AbcGeom::INuPatch::matches(alembic_header)) {
|
||||
*err_str =
|
||||
*err_str = N_(
|
||||
"Object type mismatch, Alembic object path pointed to NURBS when importing, but not any "
|
||||
"more.";
|
||||
"more.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->type != OB_CURVES_LEGACY) {
|
||||
*err_str = "Object type mismatch, Alembic object path points to NURBS.";
|
||||
*err_str = N_("Object type mismatch, Alembic object path points to NURBS.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_object.h"
|
||||
|
@ -50,14 +52,14 @@ bool AbcPointsReader::accepts_object_type(
|
|||
const char **err_str) const
|
||||
{
|
||||
if (!Alembic::AbcGeom::IPoints::matches(alembic_header)) {
|
||||
*err_str =
|
||||
*err_str = N_(
|
||||
"Object type mismatch, Alembic object path pointed to Points when importing, but not any "
|
||||
"more.";
|
||||
"more.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->type != OB_MESH) {
|
||||
*err_str = "Object type mismatch, Alembic object path points to Points.";
|
||||
*err_str = N_("Object type mismatch, Alembic object path points to Points.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_object.h"
|
||||
|
||||
using Alembic::Abc::ISampleSelector;
|
||||
|
@ -43,14 +45,14 @@ bool AbcEmptyReader::accepts_object_type(
|
|||
const char **err_str) const
|
||||
{
|
||||
if (!Alembic::AbcGeom::IXform::matches(alembic_header)) {
|
||||
*err_str =
|
||||
*err_str = N_(
|
||||
"Object type mismatch, Alembic object path pointed to XForm when importing, but not any "
|
||||
"more.";
|
||||
"more.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->type != OB_EMPTY) {
|
||||
*err_str = "Object type mismatch, Alembic object path points to XForm.";
|
||||
*err_str = N_("Object type mismatch, Alembic object path points to XForm.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -217,19 +217,19 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups)
|
|||
const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
|
||||
corner_verts[tot_loop_idx] = mesh_geometry_.global_to_local_vertices_.lookup_default(
|
||||
curr_corner.vert_index, 0);
|
||||
tot_loop_idx++;
|
||||
|
||||
/* Setup vertex group data, if needed. */
|
||||
if (dverts.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
const int group_index = curr_face.vertex_group_index;
|
||||
/* Note: face might not belong to any group */
|
||||
if (group_index >= 0 || 1) {
|
||||
MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[corner_verts[tot_loop_idx]],
|
||||
group_index);
|
||||
dw->weight = 1.0f;
|
||||
if (!dverts.is_empty()) {
|
||||
const int group_index = curr_face.vertex_group_index;
|
||||
/* Note: face might not belong to any group */
|
||||
if (group_index >= 0 || 1) {
|
||||
MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[corner_verts[tot_loop_idx]],
|
||||
group_index);
|
||||
dw->weight = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
tot_loop_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -145,6 +145,16 @@ static void rna_AnimData_action_set(PointerRNA *ptr,
|
|||
BKE_animdata_set_action(NULL, ownerId, value.data);
|
||||
}
|
||||
|
||||
static void rna_AnimData_tmpact_set(PointerRNA *ptr,
|
||||
PointerRNA value,
|
||||
struct ReportList *UNUSED(reports))
|
||||
{
|
||||
ID *ownerId = ptr->owner_id;
|
||||
|
||||
/* set action */
|
||||
BKE_animdata_set_tmpact(NULL, ownerId, value.data);
|
||||
}
|
||||
|
||||
static void rna_AnimData_tweakmode_set(PointerRNA *ptr, const bool value)
|
||||
{
|
||||
AnimData *adt = (AnimData *)ptr->data;
|
||||
|
@ -162,6 +172,34 @@ static void rna_AnimData_tweakmode_set(PointerRNA *ptr, const bool value)
|
|||
}
|
||||
}
|
||||
|
||||
/* This is used to avoid the check for NLA tracks when enabling tweak
|
||||
* mode while loading overrides. This is necessary because the normal
|
||||
* RNA tweak-mode setter refuses to enable tweak mode if there are no
|
||||
* NLA tracks since that's normally an invalid state... but the
|
||||
* overriden NLA tracks are only added *after* setting the tweak mode
|
||||
* override. */
|
||||
bool rna_AnimData_tweakmode_override_apply(Main *UNUSED(bmain),
|
||||
PointerRNA *ptr_dst,
|
||||
PointerRNA *ptr_src,
|
||||
PointerRNA *UNUSED(ptr_storage),
|
||||
PropertyRNA *UNUSED(prop_dst),
|
||||
PropertyRNA *UNUSED(prop_src),
|
||||
PropertyRNA *UNUSED(prop_storage),
|
||||
const int UNUSED(len_dst),
|
||||
const int UNUSED(len_src),
|
||||
const int UNUSED(len_storage),
|
||||
PointerRNA *UNUSED(ptr_item_dst),
|
||||
PointerRNA *UNUSED(ptr_item_src),
|
||||
PointerRNA *UNUSED(ptr_item_storage),
|
||||
IDOverrideLibraryPropertyOperation *UNUSED(opop))
|
||||
{
|
||||
AnimData *anim_data_dst = (AnimData *)ptr_dst->data;
|
||||
AnimData *anim_data_src = (AnimData *)ptr_src->data;
|
||||
|
||||
anim_data_dst->flag =(anim_data_dst->flag & ~ADT_NLA_EDIT_ON) | (anim_data_src->flag & ADT_NLA_EDIT_ON);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ****************************** */
|
||||
|
||||
/* wrapper for poll callback */
|
||||
|
@ -1372,6 +1410,16 @@ static void rna_def_animdata(BlenderRNA *brna)
|
|||
"Amount the Active Action contributes to the result of the NLA stack");
|
||||
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update"); /* this will do? */
|
||||
|
||||
/* Temporary action slot for tweak mode. */
|
||||
prop = RNA_def_property(srna, "action_tweak_storage", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "tmpact");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_EDITABLE | PROP_ID_REFCOUNT);
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, NULL, "rna_AnimData_tmpact_set", NULL, "rna_Action_id_poll");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Tweak Mode Action Storage", "Slot to temporarily hold the main action while in tweak mode");
|
||||
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_dependency_update");
|
||||
|
||||
/* Drivers */
|
||||
prop = RNA_def_property(srna, "drivers", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "drivers", NULL);
|
||||
|
@ -1397,6 +1445,7 @@ static void rna_def_animdata(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(
|
||||
prop, "Use NLA Tweak Mode", "Whether to enable or disable tweak mode in NLA");
|
||||
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update");
|
||||
RNA_def_property_override_funcs(prop, NULL, NULL, "rna_AnimData_tweakmode_override_apply");
|
||||
|
||||
prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
|
||||
|
|
|
@ -206,7 +206,7 @@ static void deformMatrices(ModifierData *md,
|
|||
int verts_num)
|
||||
{
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
BKE_armature_deform_coords_with_mesh(amd->object,
|
||||
ctx->object,
|
||||
|
|
|
@ -466,7 +466,7 @@ static void deformVerts(ModifierData *md,
|
|||
|
||||
if (ctx->object->type == OB_MESH && cmd->defgrp_name[0] != '\0') {
|
||||
/* mesh_src is only needed for vgroups. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
}
|
||||
|
||||
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
|
||||
|
@ -492,7 +492,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
Mesh *mesh_src = nullptr;
|
||||
|
||||
if (cmd->defgrp_name[0] != '\0') {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
}
|
||||
|
||||
if (mesh && BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_MDATA) {
|
||||
|
|
|
@ -95,7 +95,7 @@ static void deformVerts(ModifierData *md,
|
|||
}
|
||||
|
||||
if (mesh == nullptr) {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, nullptr, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, nullptr, nullptr);
|
||||
}
|
||||
else {
|
||||
/* Not possible to use get_mesh() in this case as we'll modify its vertices
|
||||
|
|
|
@ -90,7 +90,7 @@ static void deformVerts(ModifierData *md,
|
|||
const ModifierEvalContext *ctx,
|
||||
Mesh *mesh,
|
||||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
int /*verts_num*/)
|
||||
{
|
||||
CollisionModifierData *collmd = (CollisionModifierData *)md;
|
||||
Mesh *mesh_src;
|
||||
|
@ -107,7 +107,7 @@ static void deformVerts(ModifierData *md,
|
|||
}
|
||||
|
||||
if (mesh == nullptr) {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ob, nullptr, nullptr, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ob, nullptr, nullptr, nullptr);
|
||||
}
|
||||
else {
|
||||
/* Not possible to use get_mesh() in this case as we'll modify its vertices
|
||||
|
|
|
@ -744,7 +744,7 @@ static void deformVerts(ModifierData *md,
|
|||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
correctivesmooth_modifier_do(
|
||||
md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, uint(verts_num), nullptr);
|
||||
|
@ -761,8 +761,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(
|
||||
ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
if (mesh_src != nullptr) {
|
||||
|
|
|
@ -110,7 +110,7 @@ static void deformVerts(ModifierData *md,
|
|||
|
||||
if (ctx->object->type == OB_MESH && cmd->name[0] != '\0') {
|
||||
/* mesh_src is only needed for vgroups. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
}
|
||||
|
||||
const MDeformVert *dvert = nullptr;
|
||||
|
|
|
@ -373,7 +373,7 @@ static void deformVerts(ModifierData *md,
|
|||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, verts_num);
|
||||
|
||||
|
@ -389,8 +389,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(
|
||||
ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
if (mesh_src != nullptr) {
|
||||
|
|
|
@ -431,7 +431,7 @@ static void deformVerts(ModifierData *md,
|
|||
int verts_num)
|
||||
{
|
||||
HookModifierData *hmd = (HookModifierData *)md;
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
deformVerts_do(hmd, ctx, ctx->object, mesh_src, nullptr, vertexCos, verts_num);
|
||||
|
||||
|
|
|
@ -749,7 +749,7 @@ static void deformVerts(ModifierData *md,
|
|||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
LaplacianDeformModifier_do(
|
||||
(LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
|
||||
|
@ -766,8 +766,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(
|
||||
ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
if (mesh_src != nullptr) {
|
||||
|
|
|
@ -514,7 +514,7 @@ static void deformVerts(ModifierData *md,
|
|||
return;
|
||||
}
|
||||
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
laplaciansmoothModifier_do(
|
||||
(LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
|
||||
|
@ -537,7 +537,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
return;
|
||||
}
|
||||
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
if (mesh_src != nullptr) {
|
||||
|
|
|
@ -100,7 +100,7 @@ static void deformVerts(ModifierData *md,
|
|||
int verts_num)
|
||||
{
|
||||
LatticeModifierData *lmd = (LatticeModifierData *)md;
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ static void deformVerts(ModifierData *md,
|
|||
|
||||
if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
|
||||
/* `mesh_src` is only needed for vertex groups. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
}
|
||||
meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, verts_num);
|
||||
|
||||
|
@ -308,7 +308,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
|
||||
if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
|
||||
/* `mesh_src` is only needed for vertex groups. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
}
|
||||
if (mesh_src != nullptr) {
|
||||
BKE_mesh_wrapper_ensure_mdata(mesh_src);
|
||||
|
|
|
@ -441,7 +441,7 @@ static void deformVerts(ModifierData *md,
|
|||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
|
||||
|
||||
|
@ -459,8 +459,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(
|
||||
ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
if (mesh_src != nullptr) {
|
||||
|
|
|
@ -100,7 +100,7 @@ static void deformVerts(ModifierData *md,
|
|||
const ModifierEvalContext *ctx,
|
||||
Mesh *mesh,
|
||||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
int /*verts_num*/)
|
||||
{
|
||||
Mesh *mesh_src = mesh;
|
||||
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
|
||||
|
@ -118,10 +118,11 @@ static void deformVerts(ModifierData *md,
|
|||
}
|
||||
|
||||
if (mesh_src == nullptr) {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, nullptr, vertexCos, verts_num, true);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, nullptr, vertexCos);
|
||||
if (mesh_src == nullptr) {
|
||||
return;
|
||||
}
|
||||
BKE_mesh_orco_ensure(ctx->object, mesh_src);
|
||||
}
|
||||
|
||||
/* Clear old evaluated mesh. */
|
||||
|
@ -227,30 +228,6 @@ static void deformVerts(ModifierData *md,
|
|||
}
|
||||
}
|
||||
|
||||
/* disabled particles in editmode for now, until support for proper evaluated mesh
|
||||
* updates is coded */
|
||||
#if 0
|
||||
static void deformVertsEM(ModifierData *md,
|
||||
Object *ob,
|
||||
BMEditMesh *editData,
|
||||
Mesh *mesh,
|
||||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
{
|
||||
const bool do_temp_mesh = (mesh == nullptr);
|
||||
if (do_temp_mesh) {
|
||||
mesh = BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name);
|
||||
BM_mesh_bm_to_me(nullptr, editData->bm, mesh, &((BMeshToMeshParams){0}));
|
||||
}
|
||||
|
||||
deformVerts(md, ob, mesh, vertexCos, verts_num);
|
||||
|
||||
if (derivedData) {
|
||||
BKE_id_free(nullptr, mesh);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void panel_draw(const bContext * /*C*/, Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
|
@ -306,11 +283,7 @@ ModifierTypeInfo modifierType_ParticleSystem = {
|
|||
/*srna*/ &RNA_ParticleSystemModifier,
|
||||
/*type*/ eModifierTypeType_OnlyDeform,
|
||||
/*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
|
||||
eModifierTypeFlag_UsesPointCache
|
||||
#if 0
|
||||
| eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode
|
||||
#endif
|
||||
,
|
||||
eModifierTypeFlag_UsesPointCache,
|
||||
/*icon*/ ICON_MOD_PARTICLES,
|
||||
|
||||
/*copyData*/ copyData,
|
||||
|
|
|
@ -99,7 +99,7 @@ static void deformVerts(ModifierData *md,
|
|||
{
|
||||
/* mesh_src is needed for vgroups, but also used as ShrinkwrapCalcData.vert when projecting.
|
||||
* Avoid time-consuming mesh conversion for curves when not projecting. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
}
|
||||
|
||||
const MDeformVert *dvert = nullptr;
|
||||
|
@ -126,7 +126,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
Mesh *mesh_src = nullptr;
|
||||
|
||||
if ((swmd->vgroup_name[0] != '\0') || (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
}
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
|
|
|
@ -450,7 +450,7 @@ static void deformVerts(ModifierData *md,
|
|||
|
||||
if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
|
||||
/* mesh_src is only needed for vgroups. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
}
|
||||
|
||||
SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
|
||||
|
@ -472,7 +472,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
|
||||
if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
|
||||
/* mesh_src is only needed for vgroups. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
}
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
|
|
|
@ -183,10 +183,9 @@ static void deformVerts(ModifierData *md,
|
|||
int verts_num)
|
||||
{
|
||||
SmoothModifierData *smd = (SmoothModifierData *)md;
|
||||
Mesh *mesh_src = nullptr;
|
||||
|
||||
/* mesh_src is needed for vgroups, and taking edges into account. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
|
||||
smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, verts_num);
|
||||
|
||||
|
@ -203,10 +202,9 @@ static void deformVertsEM(ModifierData *md,
|
|||
int verts_num)
|
||||
{
|
||||
SmoothModifierData *smd = (SmoothModifierData *)md;
|
||||
Mesh *mesh_src = nullptr;
|
||||
|
||||
/* mesh_src is needed for vgroups, and taking edges into account. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
BKE_mesh_wrapper_ensure_mdata(mesh_src);
|
||||
|
|
|
@ -90,7 +90,7 @@ static void deformVerts(ModifierData *md,
|
|||
const ModifierEvalContext *ctx,
|
||||
Mesh *mesh,
|
||||
float (*vertexCos)[3],
|
||||
int verts_num)
|
||||
int /*verts_num*/)
|
||||
{
|
||||
SurfaceModifierData *surmd = (SurfaceModifierData *)md;
|
||||
const int cfra = int(DEG_get_ctime(ctx->depsgraph));
|
||||
|
@ -113,8 +113,7 @@ static void deformVerts(ModifierData *md,
|
|||
nullptr, (ID *)mesh, nullptr, LIB_ID_COPY_LOCALIZE);
|
||||
}
|
||||
else {
|
||||
surmd->runtime.mesh = MOD_deform_mesh_eval_get(
|
||||
ctx->object, nullptr, nullptr, nullptr, verts_num, false);
|
||||
surmd->runtime.mesh = MOD_deform_mesh_eval_get(ctx->object, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (!ctx->object->pd) {
|
||||
|
|
|
@ -1579,7 +1579,7 @@ static void deformVerts(ModifierData *md,
|
|||
|
||||
if (smd->defgrp_name[0] != '\0') {
|
||||
/* Only need to use mesh_src when a vgroup is used. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
}
|
||||
|
||||
surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src);
|
||||
|
@ -1601,7 +1601,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
|
||||
if (smd->defgrp_name[0] != '\0') {
|
||||
/* Only need to use mesh_src when a vgroup is used. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, nullptr);
|
||||
}
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
|
|
|
@ -164,12 +164,7 @@ void MOD_previous_vcos_store(ModifierData *md, const float (*vert_coords)[3])
|
|||
/* lattice/mesh modifier too */
|
||||
}
|
||||
|
||||
Mesh *MOD_deform_mesh_eval_get(Object *ob,
|
||||
BMEditMesh *em,
|
||||
Mesh *mesh,
|
||||
const float (*vertexCos)[3],
|
||||
const int verts_num,
|
||||
const bool use_orco)
|
||||
Mesh *MOD_deform_mesh_eval_get(Object *ob, BMEditMesh *em, Mesh *mesh, const float (*vertexCos)[3])
|
||||
{
|
||||
if (mesh != nullptr) {
|
||||
/* pass */
|
||||
|
@ -196,34 +191,16 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
|
|||
else if (vertexCos) {
|
||||
BKE_mesh_vert_coords_apply(mesh, vertexCos);
|
||||
}
|
||||
|
||||
if (use_orco) {
|
||||
BKE_mesh_orco_ensure(ob, mesh);
|
||||
}
|
||||
}
|
||||
else if (ELEM(ob->type, OB_FONT, OB_CURVES_LEGACY, OB_SURF)) {
|
||||
/* TODO(sybren): get evaluated mesh from depsgraph once
|
||||
* that's properly generated for curves. */
|
||||
mesh = BKE_mesh_new_nomain_from_curve(ob);
|
||||
|
||||
/* Currently, that may not be the case every time
|
||||
* (texts e.g. tend to give issues,
|
||||
* also when deforming curve points instead of generated curve geometry... ). */
|
||||
if (mesh != nullptr && mesh->totvert != verts_num) {
|
||||
BKE_id_free(nullptr, mesh);
|
||||
mesh = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (mesh && mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
|
||||
BLI_assert(mesh->totvert == verts_num);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void MOD_get_vgroup(
|
||||
Object *ob, Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index)
|
||||
void MOD_get_vgroup(const Object *ob,
|
||||
const Mesh *mesh,
|
||||
const char *name,
|
||||
const MDeformVert **dvert,
|
||||
int *defgrp_index)
|
||||
{
|
||||
if (mesh) {
|
||||
*defgrp_index = BKE_id_defgroup_name_index(&mesh->id, name);
|
||||
|
|
|
@ -38,12 +38,13 @@ void MOD_previous_vcos_store(ModifierData *md, const float (*vert_coords)[3]);
|
|||
Mesh *MOD_deform_mesh_eval_get(Object *ob,
|
||||
BMEditMesh *em,
|
||||
Mesh *mesh,
|
||||
const float (*vertexCos)[3],
|
||||
int verts_num,
|
||||
bool use_orco);
|
||||
const float (*vertexCos)[3]);
|
||||
|
||||
void MOD_get_vgroup(
|
||||
Object *ob, Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index);
|
||||
void MOD_get_vgroup(const Object *ob,
|
||||
const Mesh *mesh,
|
||||
const char *name,
|
||||
const MDeformVert **dvert,
|
||||
int *defgrp_index);
|
||||
|
||||
void MOD_depsgraph_update_object_bone_relation(DepsNodeHandle *node,
|
||||
Object *object,
|
||||
|
|
|
@ -347,7 +347,7 @@ static void deformVerts(ModifierData *md,
|
|||
|
||||
if (wmd->defgrp_name[0] != '\0' || wmd->texture != nullptr) {
|
||||
/* mesh_src is only needed for vgroups and textures. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
}
|
||||
|
||||
warpModifier_do(wmd, ctx, mesh_src, vertexCos, verts_num);
|
||||
|
@ -369,7 +369,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
|
||||
if (wmd->defgrp_name[0] != '\0' || wmd->texture != nullptr) {
|
||||
/* mesh_src is only needed for vgroups and textures. */
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, nullptr);
|
||||
}
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
|
|
|
@ -300,10 +300,10 @@ static void deformVerts(ModifierData *md,
|
|||
Mesh *mesh_src = nullptr;
|
||||
|
||||
if (wmd->flag & MOD_WAVE_NORM) {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, vertexCos, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, vertexCos);
|
||||
}
|
||||
else if (wmd->texture != nullptr || wmd->defgrp_name[0] != '\0') {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
|
||||
}
|
||||
|
||||
waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
|
||||
|
@ -324,10 +324,10 @@ static void deformVertsEM(ModifierData *md,
|
|||
Mesh *mesh_src = nullptr;
|
||||
|
||||
if (wmd->flag & MOD_WAVE_NORM) {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, vertexCos, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, vertexCos);
|
||||
}
|
||||
else if (wmd->texture != nullptr || wmd->defgrp_name[0] != '\0') {
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false);
|
||||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
|
||||
}
|
||||
|
||||
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
|
||||
|
|
|
@ -210,7 +210,7 @@ static std::optional<TextLayout> get_text_layout(GeoNodeExecParams ¶ms)
|
|||
/* The reason for the additional character here is unknown, but reflects other code elsewhere. */
|
||||
cu.str = static_cast<char *>(MEM_mallocN(len_bytes + sizeof(char32_t), __func__));
|
||||
cu.strinfo = static_cast<CharInfo *>(MEM_callocN((len_chars + 1) * sizeof(CharInfo), __func__));
|
||||
BLI_strncpy(cu.str, layout.text.c_str(), len_bytes + 1);
|
||||
memcpy(cu.str, layout.text.c_str(), len_bytes + 1);
|
||||
|
||||
CharTrans *chartransdata = nullptr;
|
||||
int text_len;
|
||||
|
|
Loading…
Reference in New Issue