Merge branch 'blender2.8' into blender2.8-workbench
This commit is contained in:
commit
e4ee23f780
|
@ -149,7 +149,9 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
|
|||
(glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB(
|
||||
(const GLubyte *)"glXChooseFBConfig")) == NULL ||
|
||||
(glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB(
|
||||
(const GLubyte *)"glXCreateContextAttribsARB")) == NULL)
|
||||
(const GLubyte *)"glXCreateContextAttribsARB")) == NULL ||
|
||||
(glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glXGetProcAddressARB(
|
||||
(const GLubyte *)"glXCreatePbuffer")) == NULL)
|
||||
{
|
||||
extStart = (GLubyte *)"";
|
||||
}
|
||||
|
@ -325,14 +327,8 @@ const bool GLXEW_ARB_create_context_robustness =
|
|||
|
||||
version = glGetString(GL_VERSION);
|
||||
|
||||
#if 0 // enable this when Blender switches to 3.3 core profile
|
||||
if (!version || version[0] < '3' || ((version[0] == '3') && (version[2] < '3'))) {
|
||||
fprintf(stderr, "Error! Blender requires OpenGL 3.3 to run. Try updating your drivers.\n");
|
||||
#else
|
||||
// with Mesa, the closest thing to 3.3 compatibility profile is 3.0
|
||||
if (!version || version[0] < '3') {
|
||||
fprintf(stderr, "Error! Blender requires OpenGL 3.0 (soon 3.3) to run. Try updating your drivers.\n");
|
||||
#endif
|
||||
fflush(stderr);
|
||||
/* ugly, but we get crashes unless a whole bunch of systems are patched. */
|
||||
exit(0);
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -109,6 +109,7 @@ class DATA_PT_lightprobe(DataButtonsPanel, Panel):
|
|||
col.prop(probe, "visibility_bleed_bias", "Bleed Bias")
|
||||
col.prop(probe, "visibility_blur", "Blur")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.label("Visibility Group:")
|
||||
row = col.row(align=True)
|
||||
|
@ -117,7 +118,7 @@ class DATA_PT_lightprobe(DataButtonsPanel, Panel):
|
|||
|
||||
|
||||
class DATA_PT_lightprobe_parallax(DataButtonsPanel, Panel):
|
||||
bl_label = "Parallax"
|
||||
bl_label = "Custom Parallax"
|
||||
COMPAT_ENGINES = {'BLENDER_CLAY', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
|
@ -125,14 +126,15 @@ class DATA_PT_lightprobe_parallax(DataButtonsPanel, Panel):
|
|||
engine = context.engine
|
||||
return context.lightprobe and context.lightprobe.type == 'CUBEMAP' and (engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw_header(self, context):
|
||||
probe = context.lightprobe
|
||||
self.layout.prop(probe, "use_custom_parallax", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
probe = context.lightprobe
|
||||
|
||||
layout.prop(probe, "use_custom_parallax")
|
||||
|
||||
col = layout.column()
|
||||
col.active = probe.use_custom_parallax
|
||||
|
||||
|
|
|
@ -61,10 +61,10 @@ class ToolSelectPanelHelper:
|
|||
assert(type(icon_name) is str)
|
||||
icon_value = _icon_cache.get(icon_name)
|
||||
if icon_value is None:
|
||||
dirname = bpy.utils.resource_path('SYSTEM')
|
||||
dirname = bpy.utils.resource_path('LOCAL')
|
||||
if not dirname:
|
||||
# TODO(campbell): use a better way of finding datafiles.
|
||||
dirname = bpy.utils.resource_path('LOCAL')
|
||||
dirname = bpy.utils.resource_path('SYSTEM')
|
||||
filename = os.path.join(dirname, "datafiles", "icons", icon_name + ".dat")
|
||||
try:
|
||||
icon_value = bpy.app.icons.new_triangles_from_file(filename)
|
||||
|
@ -81,7 +81,7 @@ class ToolSelectPanelHelper:
|
|||
|
||||
@staticmethod
|
||||
def _tool_is_group(tool):
|
||||
return type(tool[0]) is not str
|
||||
return type(tool) is not dict
|
||||
|
||||
@staticmethod
|
||||
def _tools_flatten(tools):
|
||||
|
@ -96,7 +96,10 @@ class ToolSelectPanelHelper:
|
|||
|
||||
@classmethod
|
||||
def _tool_vars_from_def(cls, item):
|
||||
text, icon_name, mp_idname, actions = item
|
||||
text = item["text"]
|
||||
icon_name = item["icon"]
|
||||
mp_idname = item["widget"]
|
||||
actions = item["keymap"]
|
||||
km, km_idname = (None, None) if actions is None else cls._tool_keymap[text]
|
||||
return (km_idname, mp_idname), icon_name
|
||||
|
||||
|
@ -163,8 +166,10 @@ class ToolSelectPanelHelper:
|
|||
return
|
||||
|
||||
for item in ToolSelectPanelHelper._tools_flatten(cls.tools_all()):
|
||||
text, icon_name, mp_idname, actions = item
|
||||
actions = item["keymap"]
|
||||
if actions is not None:
|
||||
text = item["text"]
|
||||
icon_name = item["icon"]
|
||||
km, km_idname = cls._km_actionmouse_simple(kc, text, icon_name, actions)
|
||||
cls._tool_keymap[text] = km, km_idname
|
||||
|
||||
|
@ -215,9 +220,9 @@ class ToolSelectPanelHelper:
|
|||
|
||||
if is_active:
|
||||
# not ideal, write this every time :S
|
||||
self._tool_group_active[item[0][0]] = index
|
||||
self._tool_group_active[item[0]["text"]] = index
|
||||
else:
|
||||
index = self._tool_group_active.get(item[0][0], 0)
|
||||
index = self._tool_group_active.get(item[0]["text"], 0)
|
||||
|
||||
item = item[index]
|
||||
use_menu = True
|
||||
|
@ -299,7 +304,7 @@ class WM_MT_toolsystem_submenu(Menu):
|
|||
icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name)
|
||||
props = layout.operator(
|
||||
"wm.tool_set",
|
||||
text=item[0],
|
||||
text=item["text"],
|
||||
icon_value=icon_value,
|
||||
)
|
||||
props.keymap = tool_def[0] or ""
|
||||
|
|
|
@ -53,18 +53,47 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|||
|
||||
# for reuse
|
||||
_tools_transform = (
|
||||
("Translate", "ops.transform.translate", "TRANSFORM_WGT_manipulator",
|
||||
(("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)),
|
||||
("Rotate", "ops.transform.rotate", "TRANSFORM_WGT_manipulator",
|
||||
(("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)),
|
||||
dict(
|
||||
text="Translate",
|
||||
icon="ops.transform.translate",
|
||||
widget="TRANSFORM_WGT_manipulator",
|
||||
keymap=(
|
||||
("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Rotate",
|
||||
icon="ops.transform.rotate",
|
||||
widget="TRANSFORM_WGT_manipulator",
|
||||
keymap=(
|
||||
("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
),
|
||||
),
|
||||
(
|
||||
("Scale", "ops.transform.resize", "TRANSFORM_WGT_manipulator",
|
||||
(("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)),
|
||||
("Scale Cage", "ops.transform.resize.cage", "VIEW3D_WGT_xform_cage", None),
|
||||
dict(
|
||||
text="Scale",
|
||||
icon="ops.transform.resize",
|
||||
widget="TRANSFORM_WGT_manipulator",
|
||||
keymap=(
|
||||
("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Scale Cage",
|
||||
icon="ops.transform.resize.cage",
|
||||
widget="VIEW3D_WGT_xform_cage",
|
||||
keymap=None,
|
||||
),
|
||||
),
|
||||
None,
|
||||
("Ruler/Protractor", "ops.view3d.ruler", "VIEW3D_WGT_ruler",
|
||||
(("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')),)),
|
||||
dict(
|
||||
text="Ruler/Protractor",
|
||||
icon="ops.view3d.ruler",
|
||||
widget="VIEW3D_WGT_ruler",
|
||||
keymap=(
|
||||
("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
),
|
||||
),
|
||||
|
||||
# DEBUGGING ONLY
|
||||
# ("Pixel Test", "tool_icon.pixeltest", None, (("wm.splash", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)),
|
||||
|
@ -72,25 +101,56 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|||
|
||||
_tools = {
|
||||
None: [
|
||||
("Cursor", "ops.generic.cursor", None,
|
||||
(("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),)),
|
||||
dict(
|
||||
text="Cursor",
|
||||
icon="ops.generic.cursor",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),
|
||||
),
|
||||
),
|
||||
|
||||
# 'Select' Group
|
||||
(
|
||||
("Select Border", "ops.generic.select_border", None, (
|
||||
("view3d.select_border", dict(deselect=False), dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
("view3d.select_border", dict(deselect=True), dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
||||
)),
|
||||
("Select Circle", "ops.generic.select_circle", None, (
|
||||
("view3d.select_circle", dict(deselect=False), dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
("view3d.select_circle", dict(deselect=True), dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
|
||||
)),
|
||||
("Select Lasso", "ops.generic.select_lasso", None, (
|
||||
("view3d.select_lasso",
|
||||
dict(deselect=False), dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
("view3d.select_lasso",
|
||||
dict(deselect=True), dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
||||
)),
|
||||
dict(
|
||||
text="Select Border",
|
||||
icon="ops.generic.select_border",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("view3d.select_border",
|
||||
dict(deselect=False),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
("view3d.select_border",
|
||||
dict(deselect=True),
|
||||
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Select Circle",
|
||||
icon="ops.generic.select_circle",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("view3d.select_circle",
|
||||
dict(deselect=False),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
("view3d.select_circle",
|
||||
dict(deselect=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Select Lasso",
|
||||
icon="ops.generic.select_lasso",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("view3d.select_lasso",
|
||||
dict(deselect=False),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
("view3d.select_lasso",
|
||||
dict(deselect=True),
|
||||
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
||||
),
|
||||
),
|
||||
),
|
||||
# End group.
|
||||
],
|
||||
|
@ -103,140 +163,260 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|||
'PAINT_WEIGHT': [
|
||||
# TODO, override brush events
|
||||
(
|
||||
("Linear Gradient", None, None, (
|
||||
("paint.weight_gradient", dict(type='LINEAR'),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
)),
|
||||
("Radial Gradient", None, None, (
|
||||
("paint.weight_gradient", dict(type='RADIAL'),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
)),
|
||||
dict(
|
||||
text="Linear Gradient",
|
||||
icon=None,
|
||||
widget=None,
|
||||
keymap=(
|
||||
("paint.weight_gradient", dict(type='LINEAR'),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Radial Gradient",
|
||||
icon=None,
|
||||
widget=None,
|
||||
keymap=(
|
||||
("paint.weight_gradient",
|
||||
dict(type='RADIAL'),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
'EDIT_ARMATURE': [
|
||||
*_tools_transform,
|
||||
("Roll", None, None, (
|
||||
("transform.transform",
|
||||
dict(release_confirm=True, mode='BONE_ROLL'),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),
|
||||
)),
|
||||
dict(
|
||||
text="Roll",
|
||||
icon=None,
|
||||
widget=None,
|
||||
keymap=(
|
||||
("transform.transform",
|
||||
dict(release_confirm=True, mode='BONE_ROLL'),
|
||||
dict(type='EVT_TWEAK_A', value='ANY'),),
|
||||
),
|
||||
),
|
||||
None,
|
||||
("Extrude Cursor", "ops.armature.extrude", None,
|
||||
(("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)),
|
||||
dict(
|
||||
text="Extrude Cursor",
|
||||
icon="ops.armature.extrude",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
],
|
||||
'EDIT_MESH': [
|
||||
*_tools_transform,
|
||||
None,
|
||||
(
|
||||
("Rip Region", "ops.mesh.rip", None, (
|
||||
("mesh.rip_move", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
("Rip Edge", "ops.mesh.rip_edge", None, (
|
||||
("mesh.rip_edge_edge_move", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
dict(
|
||||
text="Rip Region",
|
||||
icon="ops.mesh.rip",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.rip_move", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Rip Edge",
|
||||
icon="ops.mesh.rip_edge",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.rip_edge_edge_move", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
("Poly Build", "ops.mesh.polybuild_hover", None, (
|
||||
("mesh.polybuild_face_at_cursor_move",
|
||||
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
("mesh.polybuild_split_at_cursor_move",
|
||||
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
||||
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
|
||||
("mesh.polybuild_dissolve_at_cursor", dict(), dict(type='ACTIONMOUSE', value='CLICK', alt=True)),
|
||||
("mesh.polybuild_hover", dict(use_boundary=False), dict(type='MOUSEMOVE', value='ANY', alt=True)),
|
||||
("mesh.polybuild_hover", dict(use_boundary=True), dict(type='MOUSEMOVE', value='ANY', any=True)),
|
||||
)),
|
||||
dict(
|
||||
text="Poly Build",
|
||||
icon="ops.mesh.polybuild_hover",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.polybuild_face_at_cursor_move",
|
||||
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
("mesh.polybuild_split_at_cursor_move",
|
||||
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
||||
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
|
||||
("mesh.polybuild_dissolve_at_cursor", dict(), dict(type='ACTIONMOUSE', value='CLICK', alt=True)),
|
||||
("mesh.polybuild_hover", dict(use_boundary=False), dict(type='MOUSEMOVE', value='ANY', alt=True)),
|
||||
("mesh.polybuild_hover", dict(use_boundary=True), dict(type='MOUSEMOVE', value='ANY', any=True)),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
# 'Slide' Group
|
||||
(
|
||||
("Edge Slide", "ops.transform.edge_slide", None, (
|
||||
("transform.edge_slide", dict(release_confirm=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
("Vertex Slide", "ops.transform.edge_slide", None, (
|
||||
("transform.vert_slide", dict(release_confirm=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
dict(
|
||||
text="Edge Slide",
|
||||
icon="ops.transform.edge_slide",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("transform.edge_slide", dict(release_confirm=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Vertex Slide",
|
||||
icon="ops.transform.edge_slide",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("transform.vert_slide", dict(release_confirm=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
),
|
||||
# End group.
|
||||
|
||||
(
|
||||
("Spin", "ops.mesh.spin", None, (
|
||||
dict(
|
||||
text="Spin",
|
||||
icon="ops.mesh.spin",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.spin", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
("Spin (Duplicate)", "ops.mesh.spin.duplicate", None, (
|
||||
("mesh.spin", dict(dupli=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Spin (Duplicate)",
|
||||
icon="ops.mesh.spin.duplicate",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.spin", dict(dupli=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
("Inset Faces", "ops.mesh.inset", None, (
|
||||
("mesh.inset", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
|
||||
(
|
||||
("Extrude Region", "ops.view3d.edit_mesh_extrude", None, (
|
||||
("view3d.edit_mesh_extrude", dict(),
|
||||
dict(
|
||||
text="Inset Faces",
|
||||
icon="ops.mesh.inset",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.inset", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
("Extrude Individual", "ops.view3d.edit_mesh_extrude_individual", None, (
|
||||
("mesh.extrude_faces_move", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
),
|
||||
),
|
||||
|
||||
(
|
||||
("Randomize", "ops.transform.vertex_random", None, (
|
||||
("transform.vertex_random", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
("Smooth", "ops.mesh.vertices_smooth", None, (
|
||||
("mesh.vertices_smooth", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
dict(
|
||||
text="Extrude Region",
|
||||
icon="ops.view3d.edit_mesh_extrude",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("view3d.edit_mesh_extrude", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Extrude Individual",
|
||||
icon="ops.view3d.edit_mesh_extrude_individual",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.extrude_faces_move", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
(
|
||||
("Shrink/Fatten", "ops.transform.shrink_fatten", None, (
|
||||
("transform.shrink_fatten", dict(release_confirm=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
("Push/Pull", "ops.transform.push_pull", None, (
|
||||
("transform.push_pull", dict(release_confirm=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
)),
|
||||
dict(
|
||||
text="Randomize",
|
||||
icon="ops.transform.vertex_random",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("transform.vertex_random", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Smooth",
|
||||
icon="ops.mesh.vertices_smooth",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.vertices_smooth", dict(),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
(
|
||||
dict(
|
||||
text="Shrink/Fatten",
|
||||
icon="ops.transform.shrink_fatten",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("transform.shrink_fatten", dict(release_confirm=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Push/Pull",
|
||||
icon="ops.transform.push_pull",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("transform.push_pull", dict(release_confirm=True),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
# Knife Group
|
||||
(
|
||||
("Knife", "ops.mesh.knife_tool", None, (
|
||||
("mesh.knife_tool",
|
||||
dict(wait_for_input=False, use_occlude_geometry=True, only_selected=False),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),)),
|
||||
dict(
|
||||
text="Knife",
|
||||
icon="ops.mesh.knife_tool",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.knife_tool",
|
||||
dict(wait_for_input=False, use_occlude_geometry=True, only_selected=False),
|
||||
dict(type='ACTIONMOUSE', value='PRESS')),),
|
||||
),
|
||||
None,
|
||||
("Bisect", "ops.mesh.bisect", None, (
|
||||
("mesh.bisect",
|
||||
dict(),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),)),
|
||||
dict(
|
||||
text="Bisect",
|
||||
icon="ops.mesh.bisect",
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.bisect",
|
||||
dict(),
|
||||
dict(type='EVT_TWEAK_A', value='ANY')),),
|
||||
),
|
||||
),
|
||||
# End group.
|
||||
("Extrude Cursor", None, None,
|
||||
(("mesh.dupli_extrude_cursor", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)),
|
||||
dict(
|
||||
text="Extrude Cursor",
|
||||
icon=None,
|
||||
widget=None,
|
||||
keymap=(
|
||||
("mesh.dupli_extrude_cursor", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
],
|
||||
'EDIT_CURVE': [
|
||||
*_tools_transform,
|
||||
None,
|
||||
("Draw", None, None,
|
||||
(("curve.draw", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),)),
|
||||
("Extrude Cursor", None, None,
|
||||
(("curve.vertex_add", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)),
|
||||
dict(
|
||||
text="Draw",
|
||||
icon=None,
|
||||
widget=None,
|
||||
keymap=(
|
||||
("curve.draw", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
dict(
|
||||
text="Extrude Cursor",
|
||||
icon=None,
|
||||
widget=None,
|
||||
keymap=(
|
||||
("curve.vertex_add", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
||||
),
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -289,47 +289,6 @@ static bool get_path_user(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special convenience exception for dev builds to allow overrides to the system path.
|
||||
* With this, need for running 'make install' can be avoided, e.g. by symlinking SOURCE_DIR/release
|
||||
* to EXECUTABLE_DIR/release, or by running Blender from source directory directly.
|
||||
*/
|
||||
static bool get_path_system_dev_build_exception(
|
||||
char *targetpath, size_t targetpath_len, const char *relfolder)
|
||||
{
|
||||
char cwd[FILE_MAX];
|
||||
char tmp_path[FILE_MAX];
|
||||
bool ret = false;
|
||||
|
||||
/* Try EXECUTABLE_DIR/release/folder_name. Allows symlinking release folder from source dir. */
|
||||
if (test_path(targetpath, targetpath_len, bprogdir, "release", relfolder)) {
|
||||
ret = true;
|
||||
}
|
||||
/* Try CWD/release/folder_name. Allows executing Blender from any directory
|
||||
* (usually source dir), even without a release dir in bprogdir. */
|
||||
if (BLI_current_working_dir(cwd, sizeof(cwd))) {
|
||||
if (test_path(targetpath, targetpath_len, cwd, "release", relfolder)) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure we are in source dir, not in another one that happens to have a release folder. */
|
||||
if (ret) {
|
||||
BLI_join_dirfile(tmp_path, sizeof(tmp_path), bprogdir,
|
||||
"source" SEP_STR "blender" SEP_STR "blenkernel" SEP_STR "BKE_blender_version.h");
|
||||
if (!BLI_is_file(tmp_path)) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* never use if not existing. */
|
||||
if (!ret) {
|
||||
targetpath[0] = '\0';
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path of a folder within the Blender installation directory.
|
||||
*
|
||||
|
@ -360,10 +319,6 @@ static bool get_path_system(
|
|||
relfolder[0] = '\0';
|
||||
}
|
||||
|
||||
if (get_path_system_dev_build_exception(targetpath, targetpath_len, relfolder)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
system_path[0] = '\0';
|
||||
|
||||
if (test_env_path(system_path, envvar)) {
|
||||
|
@ -376,19 +331,10 @@ static bool get_path_system(
|
|||
}
|
||||
}
|
||||
|
||||
const char *blender_version_str = blender_version_decimal(ver);
|
||||
system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_str);
|
||||
system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver));
|
||||
if (system_base_path)
|
||||
BLI_strncpy(system_path, system_base_path, FILE_MAX);
|
||||
|
||||
/* GHOST_getSystemDir returns nothing in case of portable install, so we try binary directory itself. */
|
||||
if (!system_path[0]) {
|
||||
const char *prog_dir = BKE_appdir_program_dir();
|
||||
if (prog_dir != NULL) {
|
||||
BLI_join_dirfile(system_path, sizeof(system_path), prog_dir, blender_version_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!system_path[0])
|
||||
return false;
|
||||
|
||||
|
|
|
@ -1530,7 +1530,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
|
|||
MLoop *ml, *mloop = MEM_malloc_arrayN(totloop, sizeof(*mloop), __func__);
|
||||
int *oldl = MEM_malloc_arrayN(totloop, sizeof(*oldl), __func__);
|
||||
#ifdef USE_LOOPS
|
||||
int newl = MEM_malloc_arrayN(totloop, sizeof(*newl), __func__);
|
||||
int *newl = MEM_malloc_arrayN(totloop, sizeof(*newl), __func__);
|
||||
#endif
|
||||
STACK_DECLARE(mloop);
|
||||
STACK_DECLARE(oldl);
|
||||
|
|
|
@ -1429,6 +1429,7 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int fla
|
|||
#endif
|
||||
|
||||
/* the duplicate should get a copy of the animdata */
|
||||
BLI_assert((flag & LIB_ID_COPY_ACTIONS) == 0 || (flag & LIB_ID_CREATE_NO_MAIN) == 0);
|
||||
id_copy_animdata(bmain, new_id, (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0);
|
||||
|
||||
if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0) {
|
||||
|
|
|
@ -102,7 +102,8 @@ Depsgraph::Depsgraph(Scene *scene,
|
|||
scene(scene),
|
||||
view_layer(view_layer),
|
||||
mode(mode),
|
||||
ctime(BKE_scene_frame_get(scene))
|
||||
ctime(BKE_scene_frame_get(scene)),
|
||||
scene_cow(NULL)
|
||||
{
|
||||
BLI_spin_init(&lock);
|
||||
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
|
||||
|
|
|
@ -197,6 +197,11 @@ struct Depsgraph {
|
|||
|
||||
/* Time at which dependency graph is being or was last evaluated. */
|
||||
float ctime;
|
||||
|
||||
/* Evaluated version of datablocks we access a lot.
|
||||
* Stored here to save us form doing hash lookup.
|
||||
*/
|
||||
Scene *scene_cow;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
|
|
|
@ -260,6 +260,9 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
|
|||
/* Relations are up to date. */
|
||||
deg_graph->need_update = false;
|
||||
|
||||
/* Store pointers to commonly used valuated datablocks. */
|
||||
deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(°_graph->scene->id);
|
||||
|
||||
if (need_on_visible_update) {
|
||||
DEG_graph_on_visible_update(bmain, graph);
|
||||
}
|
||||
|
|
|
@ -105,13 +105,12 @@ Scene *DEG_get_evaluated_scene(const Depsgraph *graph)
|
|||
{
|
||||
const DEG::Depsgraph *deg_graph =
|
||||
reinterpret_cast<const DEG::Depsgraph *>(graph);
|
||||
Scene *scene_orig = deg_graph->scene;
|
||||
Scene *scene_cow =
|
||||
reinterpret_cast<Scene *>(deg_graph->get_cow_id(&scene_orig->id));
|
||||
Scene *scene_cow = deg_graph->scene_cow;
|
||||
/* TODO(sergey): Shall we expand datablock here? Or is it OK to assume
|
||||
* that calleer is OK with just a pointer in case scene is not up[dated
|
||||
* yet?
|
||||
*/
|
||||
BLI_assert(DEG::deg_copy_on_write_is_expanded(&scene_cow->id));
|
||||
return scene_cow;
|
||||
}
|
||||
|
||||
|
@ -120,19 +119,6 @@ ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph)
|
|||
const DEG::Depsgraph *deg_graph =
|
||||
reinterpret_cast<const DEG::Depsgraph *>(graph);
|
||||
Scene *scene_cow = DEG_get_evaluated_scene(graph);
|
||||
/* We update copy-on-write scene in the following cases:
|
||||
* - It was not expanded yet.
|
||||
* - It was tagged for update of CoW component.
|
||||
* This allows us to have proper view layer pointer.
|
||||
*/
|
||||
if (DEG_depsgraph_use_copy_on_write() &&
|
||||
(!DEG::deg_copy_on_write_is_expanded(&scene_cow->id) ||
|
||||
scene_cow->id.recalc & ID_RECALC_COPY_ON_WRITE))
|
||||
{
|
||||
const DEG::IDDepsNode *id_node =
|
||||
deg_graph->find_id_node(°_graph->scene->id);
|
||||
DEG::deg_update_copy_on_write_datablock(deg_graph, id_node);
|
||||
}
|
||||
/* Do name-based lookup. */
|
||||
/* TODO(sergey): Can this be optimized? */
|
||||
ViewLayer *view_layer_orig = deg_graph->view_layer;
|
||||
|
|
|
@ -209,11 +209,6 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
|
|||
return;
|
||||
}
|
||||
|
||||
/* TODO: Calling this forces the scene datablock to be expanded,
|
||||
* otherwise we get crashes on load with copy-on-write. There may
|
||||
* be a better solution for this. */
|
||||
DEG_get_evaluated_view_layer(depsgraph);
|
||||
|
||||
iter->data = data;
|
||||
data->dupli_parent = NULL;
|
||||
data->dupli_list = NULL;
|
||||
|
|
|
@ -39,12 +39,14 @@
|
|||
#include "BLI_ghash.h"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "atomic_ops.h"
|
||||
|
||||
#include "intern/eval/deg_eval_copy_on_write.h"
|
||||
#include "intern/eval/deg_eval_flush.h"
|
||||
#include "intern/eval/deg_eval_stats.h"
|
||||
#include "intern/nodes/deg_node.h"
|
||||
|
@ -219,6 +221,25 @@ static void schedule_children(TaskPool *pool,
|
|||
}
|
||||
}
|
||||
|
||||
static void depsgraph_ensure_view_layer(Depsgraph *graph)
|
||||
{
|
||||
/* We update copy-on-write scene in the following cases:
|
||||
* - It was not expanded yet.
|
||||
* - It was tagged for update of CoW component.
|
||||
* This allows us to have proper view layer pointer.
|
||||
*/
|
||||
if (!DEG_depsgraph_use_copy_on_write()) {
|
||||
return;
|
||||
}
|
||||
Scene *scene_cow = graph->scene_cow;
|
||||
if (!deg_copy_on_write_is_expanded(&scene_cow->id) ||
|
||||
scene_cow->id.recalc & ID_RECALC_COPY_ON_WRITE)
|
||||
{
|
||||
const IDDepsNode *id_node = graph->find_id_node(&graph->scene->id);
|
||||
deg_update_copy_on_write_datablock(graph, id_node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate all nodes tagged for updating,
|
||||
* \warning This is usually done as part of main loop, but may also be
|
||||
|
@ -234,12 +255,7 @@ void deg_evaluate_on_refresh(Depsgraph *graph)
|
|||
}
|
||||
const bool do_time_debug = ((G.debug & G_DEBUG_DEPSGRAPH_TIME) != 0);
|
||||
const double start_time = do_time_debug ? PIL_check_seconds_timer() : 0;
|
||||
|
||||
/* TODO: Calling this forces the scene datablock to be expanded,
|
||||
* otherwise we get crashes on load with copy-on-write. There may
|
||||
* be a better solution for this. */
|
||||
DEG_get_evaluated_view_layer((const ::Depsgraph*)graph);
|
||||
|
||||
depsgraph_ensure_view_layer(graph);
|
||||
/* Set up evaluation state. */
|
||||
DepsgraphEvalState state;
|
||||
state.graph = graph;
|
||||
|
|
|
@ -289,7 +289,6 @@ bool scene_copy_inplace_no_main(const Scene *scene, Scene *new_scene)
|
|||
bool result = BKE_id_copy_ex(NULL,
|
||||
id_for_copy,
|
||||
(ID **)&new_scene,
|
||||
LIB_ID_COPY_ACTIONS |
|
||||
LIB_ID_CREATE_NO_MAIN |
|
||||
LIB_ID_CREATE_NO_USER_REFCOUNT |
|
||||
LIB_ID_CREATE_NO_ALLOCATE |
|
||||
|
@ -490,6 +489,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
|
|||
{
|
||||
const ID *id_orig = id_node->id_orig;
|
||||
ID *id_cow = id_node->id_cow;
|
||||
const int id_cow_recalc = id_cow->recalc;
|
||||
/* No need to expand such datablocks, their copied ID is same as original
|
||||
* one already.
|
||||
*/
|
||||
|
@ -582,6 +582,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
|
|||
if (newid != NULL) {
|
||||
MEM_freeN(newid);
|
||||
}
|
||||
id_cow->recalc = id_orig->recalc | id_cow_recalc;
|
||||
return id_cow;
|
||||
}
|
||||
|
||||
|
|
|
@ -301,7 +301,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
|
|||
flush_editors_id_update(bmain, graph, &update_ctx);
|
||||
}
|
||||
|
||||
static void graph_clear_func(
|
||||
static void graph_clear_operation_func(
|
||||
void *__restrict data_v,
|
||||
const int i,
|
||||
const ParallelRangeTLS *__restrict /*tls*/)
|
||||
|
@ -312,18 +312,41 @@ static void graph_clear_func(
|
|||
node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE);
|
||||
}
|
||||
|
||||
static void graph_clear_id_node_func(
|
||||
void *__restrict data_v,
|
||||
const int i,
|
||||
const ParallelRangeTLS *__restrict /*tls*/)
|
||||
{
|
||||
Depsgraph *graph = (Depsgraph *)data_v;
|
||||
IDDepsNode *id_node = graph->id_nodes[i];
|
||||
id_node->id_cow->recalc &= ~ID_RECALC_ALL;
|
||||
}
|
||||
|
||||
/* Clear tags from all operation nodes. */
|
||||
void deg_graph_clear_tags(Depsgraph *graph)
|
||||
{
|
||||
/* Go over all operation nodes, clearing tags. */
|
||||
const int num_operations = graph->operations.size();
|
||||
ParallelRangeSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
settings.min_iter_per_thread = 1024;
|
||||
BLI_task_parallel_range(0, num_operations,
|
||||
graph,
|
||||
graph_clear_func,
|
||||
&settings);
|
||||
{
|
||||
const int num_operations = graph->operations.size();
|
||||
ParallelRangeSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
settings.min_iter_per_thread = 1024;
|
||||
BLI_task_parallel_range(0, num_operations,
|
||||
graph,
|
||||
graph_clear_operation_func,
|
||||
&settings);
|
||||
}
|
||||
/* Go over all ID nodes nodes, clearing tags. */
|
||||
{
|
||||
const int num_id_nodes = graph->id_nodes.size();
|
||||
ParallelRangeSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
settings.min_iter_per_thread = 1024;
|
||||
BLI_task_parallel_range(0, num_id_nodes,
|
||||
graph,
|
||||
graph_clear_id_node_func,
|
||||
&settings);
|
||||
}
|
||||
/* Clear any entry tags which haven't been flushed. */
|
||||
BLI_gset_clear(graph->entry_tags, NULL);
|
||||
}
|
||||
|
|
|
@ -33,10 +33,13 @@
|
|||
#include "intern/depsgraph_intern.h"
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
void TimeSourceDepsNode::tag_update(Depsgraph *graph)
|
||||
{
|
||||
graph->scene_cow->id.recalc |= ID_RECALC_TIME;
|
||||
foreach (DepsRelation *rel, outlinks) {
|
||||
DepsNode *node = rel->to;
|
||||
node->tag_update(graph);
|
||||
|
|
|
@ -1361,6 +1361,11 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
|
|||
DrawEngineType *draw_engine_type = engine_type->draw_engine;
|
||||
RenderData *r = &scene->r;
|
||||
Render *render = engine->re;
|
||||
|
||||
if (G.background && DST.ogl_context == NULL) {
|
||||
WM_init_opengl();
|
||||
}
|
||||
|
||||
/* Changing Context */
|
||||
DRW_opengl_context_enable();
|
||||
/* IMPORTANT: We dont support immediate mode in render mode!
|
||||
|
@ -2049,13 +2054,16 @@ void DRW_opengl_context_create(void)
|
|||
BLI_assert(DST.ogl_context == NULL); /* Ensure it's called once */
|
||||
|
||||
BLI_mutex_init(&DST.ogl_context_mutex);
|
||||
|
||||
immDeactivate();
|
||||
if (!G.background) {
|
||||
immDeactivate();
|
||||
}
|
||||
/* This changes the active context. */
|
||||
DST.ogl_context = WM_opengl_context_create();
|
||||
/* Be sure to create gawain.context too. */
|
||||
DST.gwn_context = GWN_context_create();
|
||||
immActivate();
|
||||
if (!G.background) {
|
||||
immActivate();
|
||||
}
|
||||
/* Set default Blender OpenGL state */
|
||||
GPU_state_init();
|
||||
/* So we activate the window's one afterwards. */
|
||||
|
@ -2082,12 +2090,16 @@ void DRW_opengl_context_enable(void)
|
|||
* multiple threads. */
|
||||
BLI_mutex_lock(&DST.ogl_context_mutex);
|
||||
if (BLI_thread_is_main()) {
|
||||
immDeactivate();
|
||||
if (!G.background) {
|
||||
immDeactivate();
|
||||
}
|
||||
}
|
||||
WM_opengl_context_activate(DST.ogl_context);
|
||||
GWN_context_active_set(DST.gwn_context);
|
||||
if (BLI_thread_is_main()) {
|
||||
immActivate();
|
||||
if (!G.background) {
|
||||
immActivate();
|
||||
}
|
||||
BLF_batch_reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2276,6 +2276,7 @@ static void OBJECT_draw_scene(void *vedata)
|
|||
/* This has to be freed only after drawing empties! */
|
||||
if (stl->g_data->image_plane_map) {
|
||||
BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN);
|
||||
stl->g_data->image_plane_map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -925,59 +925,60 @@ void POSE_OT_select_grouped(wmOperatorType *ot)
|
|||
static int pose_select_mirror_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob_act = CTX_data_active_object(C);
|
||||
Object *ob = BKE_object_pose_armature_get(ob_act);
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan, *pchan_mirror_act = NULL;
|
||||
const bool active_only = RNA_boolean_get(op->ptr, "only_active");
|
||||
const bool extend = RNA_boolean_get(op->ptr, "extend");
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
||||
if ((ob && (ob->mode & OB_MODE_POSE)) == 0) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, OB_MODE_POSE, ob)
|
||||
{
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan, *pchan_mirror_act = NULL;
|
||||
const bool active_only = RNA_boolean_get(op->ptr, "only_active");
|
||||
const bool extend = RNA_boolean_get(op->ptr, "extend");
|
||||
|
||||
arm = ob->data;
|
||||
arm = ob->data;
|
||||
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
const int flag = (pchan->bone->flag & BONE_SELECTED);
|
||||
PBONE_PREV_FLAG_SET(pchan, flag);
|
||||
}
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
const int flag = (pchan->bone->flag & BONE_SELECTED);
|
||||
PBONE_PREV_FLAG_SET(pchan, flag);
|
||||
}
|
||||
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (PBONE_SELECTABLE(arm, pchan->bone)) {
|
||||
bPoseChannel *pchan_mirror;
|
||||
int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0;
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (PBONE_SELECTABLE(arm, pchan->bone)) {
|
||||
bPoseChannel *pchan_mirror;
|
||||
int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0;
|
||||
|
||||
if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) &&
|
||||
(PBONE_VISIBLE(arm, pchan_mirror->bone)))
|
||||
{
|
||||
const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror);
|
||||
flag_new |= flag_mirror;
|
||||
if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) &&
|
||||
(PBONE_VISIBLE(arm, pchan_mirror->bone)))
|
||||
{
|
||||
const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror);
|
||||
flag_new |= flag_mirror;
|
||||
|
||||
if (pchan->bone == arm->act_bone) {
|
||||
pchan_mirror_act = pchan_mirror;
|
||||
if (pchan->bone == arm->act_bone) {
|
||||
pchan_mirror_act = pchan_mirror;
|
||||
}
|
||||
|
||||
/* skip all but the active or its mirror */
|
||||
if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip all but the active or its mirror */
|
||||
if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) {
|
||||
continue;
|
||||
}
|
||||
pchan->bone->flag = (pchan->bone->flag & ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) | flag_new;
|
||||
}
|
||||
|
||||
pchan->bone->flag = (pchan->bone->flag & ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) | flag_new;
|
||||
}
|
||||
}
|
||||
|
||||
if (pchan_mirror_act) {
|
||||
arm->act_bone = pchan_mirror_act->bone;
|
||||
if (pchan_mirror_act) {
|
||||
arm->act_bone = pchan_mirror_act->bone;
|
||||
|
||||
/* in weightpaint we select the associated vertex group too */
|
||||
if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
|
||||
ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name);
|
||||
DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
|
||||
/* in weightpaint we select the associated vertex group too */
|
||||
if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
|
||||
ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name);
|
||||
DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
|
||||
}
|
||||
FOREACH_OBJECT_IN_MODE_END;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
|
@ -1229,4 +1229,9 @@ void UI_widgetbase_draw_cache_begin(void);
|
|||
void UI_widgetbase_draw_cache_flush(void);
|
||||
void UI_widgetbase_draw_cache_end(void);
|
||||
|
||||
/* Special drawing for toolbar, mainly workarounds for inflexible icon sizing. */
|
||||
#define USE_TOOLBAR_HACK
|
||||
|
||||
bool UI_but_is_tool(const uiBut *but);
|
||||
|
||||
#endif /* __UI_INTERFACE_H__ */
|
||||
|
|
|
@ -49,6 +49,8 @@ typedef struct IconFile {
|
|||
#define ICON_DEFAULT_HEIGHT 16
|
||||
#define ICON_DEFAULT_WIDTH 16
|
||||
|
||||
#define ICON_DEFAULT_HEIGHT_TOOLBAR 38
|
||||
|
||||
#define ICON_DEFAULT_HEIGHT_SCALE ((int)(UI_UNIT_Y * 0.8f))
|
||||
#define ICON_DEFAULT_WIDTH_SCALE ((int)(UI_UNIT_X * 0.8f))
|
||||
|
||||
|
|
|
@ -10232,3 +10232,18 @@ void ui_but_clipboard_free(void)
|
|||
{
|
||||
curvemapping_free_data(&but_copypaste_curve);
|
||||
}
|
||||
|
||||
bool UI_but_is_tool(const uiBut *but)
|
||||
{
|
||||
/* very evil! */
|
||||
if (but->optype != NULL) {
|
||||
static wmOperatorType *ot = NULL;
|
||||
if (ot == NULL) {
|
||||
ot = WM_operatortype_find("WM_OT_tool_set", false);
|
||||
}
|
||||
if (but->optype == ot) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1226,14 +1226,15 @@ static void icon_draw_size(
|
|||
/* We need to flush widget base first to ensure correct ordering. */
|
||||
UI_widgetbase_draw_cache_flush();
|
||||
|
||||
#ifdef USE_TOOLBAR_HACK
|
||||
/* TODO(campbell): scale icons up for toolbar, we need a way to detect larger buttons and do this automatic. */
|
||||
{
|
||||
/* Icons are currently 38 aligned, scale from 16 -> 38. */
|
||||
float scale = 2.375f;
|
||||
float scale = (float)ICON_DEFAULT_HEIGHT_TOOLBAR / (float)ICON_DEFAULT_HEIGHT;
|
||||
y = (y + (h / 2)) - ((h * scale) / 2);
|
||||
w *= scale;
|
||||
h *= scale;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This could re-generate often if rendered at different sizes in the one interface.
|
||||
* TODO(campbell): support caching multiple sizes. */
|
||||
|
|
|
@ -105,6 +105,8 @@ typedef enum {
|
|||
UI_WTYPE_PROGRESSBAR,
|
||||
} uiWidgetTypeEnum;
|
||||
|
||||
#define UI_MENU_WIDTH_MIN (UI_UNIT_Y * 9)
|
||||
|
||||
/* menu scrolling */
|
||||
#define UI_MENU_SCROLL_ARROW 12
|
||||
#define UI_MENU_SCROLL_MOUSE (UI_MENU_SCROLL_ARROW + 2)
|
||||
|
|
|
@ -902,7 +902,23 @@ static void ui_item_menu_hold(struct bContext *C, ARegion *butregion, uiBut *but
|
|||
|
||||
block->flag |= UI_BLOCK_POPUP_HOLD;
|
||||
block->flag |= UI_BLOCK_IS_FLIP;
|
||||
UI_block_direction_set(block, UI_DIR_DOWN);
|
||||
|
||||
char direction = UI_DIR_DOWN;
|
||||
if (!but->drawstr[0]) {
|
||||
if (butregion->alignment == RGN_ALIGN_LEFT) {
|
||||
direction = UI_DIR_RIGHT;
|
||||
}
|
||||
else if (butregion->alignment == RGN_ALIGN_RIGHT) {
|
||||
direction = UI_DIR_LEFT;
|
||||
}
|
||||
else if (butregion->alignment == RGN_ALIGN_BOTTOM) {
|
||||
direction = UI_DIR_UP;
|
||||
}
|
||||
else {
|
||||
direction = UI_DIR_DOWN;
|
||||
}
|
||||
}
|
||||
UI_block_direction_set(block, direction);
|
||||
|
||||
const char *menu_id = but->hold_argN;
|
||||
MenuType *mt = WM_menutype_find(menu_id, true);
|
||||
|
|
|
@ -76,7 +76,7 @@ static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handl
|
|||
uiPieMenu *pie = arg_pie;
|
||||
int minwidth, width, height;
|
||||
|
||||
minwidth = 50;
|
||||
minwidth = UI_MENU_WIDTH_MIN;
|
||||
block = pie->block_radial;
|
||||
|
||||
/* in some cases we create the block before the region,
|
||||
|
|
|
@ -191,7 +191,13 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||
|
||||
if (pup->but) {
|
||||
/* minimum width to enforece */
|
||||
minwidth = BLI_rctf_size_x(&pup->but->rect);
|
||||
if (pup->but->drawstr[0]) {
|
||||
minwidth = BLI_rctf_size_x(&pup->but->rect);
|
||||
}
|
||||
else {
|
||||
/* For buttons with no text, use the minimum (typically icon only). */
|
||||
minwidth = UI_MENU_WIDTH_MIN;
|
||||
}
|
||||
|
||||
/* settings (typically rna-enum-popups) show above the button,
|
||||
* menu's like file-menu, show below */
|
||||
|
@ -209,7 +215,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||
}
|
||||
}
|
||||
else {
|
||||
minwidth = 50;
|
||||
minwidth = UI_MENU_WIDTH_MIN;
|
||||
direction = UI_DIR_DOWN;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
|
|||
minwidth = BLI_rctf_size_x(&pup->but->rect);
|
||||
}
|
||||
else {
|
||||
minwidth = 50;
|
||||
minwidth = UI_MENU_WIDTH_MIN;
|
||||
}
|
||||
|
||||
block = pup->block;
|
||||
|
|
|
@ -208,8 +208,8 @@ static const uint g_shape_preset_checkmark_face[4][3] = {
|
|||
{3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}
|
||||
};
|
||||
|
||||
#define OY -0.2
|
||||
#define SC 0.35
|
||||
#define OY (-0.2 / 2)
|
||||
#define SC (0.35 * 2)
|
||||
static const float g_shape_preset_hold_action_vert[6][2] = {
|
||||
{-0.5 + SC, 1.0 + OY}, {0.5, 1.0 + OY}, {0.5, 0.0 + OY + SC},
|
||||
};
|
||||
|
@ -1255,9 +1255,9 @@ static int ui_but_draw_menu_icon(const uiBut *but)
|
|||
|
||||
/* icons have been standardized... and this call draws in untransformed coordinates */
|
||||
|
||||
static void widget_draw_icon(
|
||||
const uiBut *but, BIFIconID icon, float alpha, const rcti *rect,
|
||||
const bool show_menu_icon)
|
||||
static void widget_draw_icon_ex(
|
||||
const uiBut *but, BIFIconID icon, float alpha, const rcti *rect, const bool show_menu_icon,
|
||||
const int icon_size)
|
||||
{
|
||||
float xs = 0.0f, ys = 0.0f;
|
||||
float aspect, height;
|
||||
|
@ -1273,7 +1273,7 @@ static void widget_draw_icon(
|
|||
if (icon == ICON_BLANK1 && (but->flag & UI_BUT_ICON_SUBMENU) == 0) return;
|
||||
|
||||
aspect = but->block->aspect / UI_DPI_FAC;
|
||||
height = ICON_DEFAULT_HEIGHT / aspect;
|
||||
height = icon_size / aspect;
|
||||
|
||||
/* calculate blend color */
|
||||
if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_ROW, UI_BTYPE_TOGGLE_N, UI_BTYPE_LISTROW)) {
|
||||
|
@ -1337,6 +1337,12 @@ static void widget_draw_icon(
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
static void widget_draw_icon(
|
||||
const uiBut *but, BIFIconID icon, float alpha, const rcti *rect, const bool show_menu_icon)
|
||||
{
|
||||
widget_draw_icon_ex(but, icon, alpha, rect, show_menu_icon, ICON_DEFAULT_HEIGHT);
|
||||
}
|
||||
|
||||
static void ui_text_clip_give_prev_off(uiBut *but, const char *str)
|
||||
{
|
||||
const char *prev_utf8 = BLI_str_find_prev_char_utf8(str, str + but->ofs);
|
||||
|
@ -1998,12 +2004,26 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
|
|||
}
|
||||
/* Icons on the left with optional text label on the right */
|
||||
else if (but->flag & UI_HAS_ICON || show_menu_icon) {
|
||||
const bool is_tool = UI_but_is_tool(but);
|
||||
|
||||
const BIFIconID icon = (but->flag & UI_HAS_ICON) ? but->icon + but->iconadd : ICON_NONE;
|
||||
const float icon_size = ICON_DEFAULT_WIDTH_SCALE;
|
||||
int icon_size_init = is_tool ? ICON_DEFAULT_HEIGHT_TOOLBAR : ICON_DEFAULT_HEIGHT;
|
||||
const float icon_size = icon_size_init / (but->block->aspect / UI_DPI_FAC);
|
||||
|
||||
#ifdef USE_TOOLBAR_HACK
|
||||
if (is_tool) {
|
||||
/* pass (even if its a menu toolbar) */
|
||||
but->drawflag |= UI_BUT_TEXT_LEFT;
|
||||
but->drawflag |= UI_BUT_ICON_LEFT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* menu item - add some more padding so menus don't feel cramped. it must
|
||||
* be part of the button so that this area is still clickable */
|
||||
if (ui_block_is_pie_menu(but->block)) {
|
||||
if (is_tool) {
|
||||
/* pass (even if its a menu toolbar) */
|
||||
}
|
||||
else if (ui_block_is_pie_menu(but->block)) {
|
||||
if (but->dt == UI_EMBOSS_RADIAL)
|
||||
rect->xmin += 0.3f * U.widget_unit;
|
||||
}
|
||||
|
@ -2148,7 +2168,7 @@ static struct uiWidgetColors wcol_option = {
|
|||
1,
|
||||
15, -15,
|
||||
0,
|
||||
0.2f,
|
||||
0.3333333f,
|
||||
};
|
||||
|
||||
/* button that shows popup */
|
||||
|
@ -3162,7 +3182,7 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
|
|||
bTheme *btheme = UI_GetTheme();
|
||||
uiWidgetColors *wcol = &btheme->tui.wcol_numslider;
|
||||
uiWidgetBase wtb;
|
||||
const float rad = wcol->roundness * U.widget_unit;
|
||||
const float rad = wcol->roundness * BLI_rcti_size_x(rect);
|
||||
float x, y;
|
||||
float rgb[3], hsv[3], v;
|
||||
bool color_profile = but->block->color_profile;
|
||||
|
@ -3250,7 +3270,7 @@ static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol)
|
|||
static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign, bool emboss)
|
||||
{
|
||||
uiWidgetBase wtb;
|
||||
const float rad = wcol->roundness * U.widget_unit;
|
||||
const float rad = wcol->roundness * BLI_rcti_size_y(rect);
|
||||
const int handle_width = min_ii(BLI_rcti_size_x(rect) / 3, BLI_rcti_size_y(rect) * 0.7f);
|
||||
|
||||
if (state & UI_SELECT)
|
||||
|
@ -3510,7 +3530,7 @@ static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int
|
|||
|
||||
/* round corners */
|
||||
float value = but->a1;
|
||||
float offs = wcol->roundness * U.widget_unit;
|
||||
float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog);
|
||||
float w = value * BLI_rcti_size_x(&rect_prog);
|
||||
|
||||
/* ensure minimium size */
|
||||
|
@ -3546,7 +3566,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
|
|||
|
||||
/* backdrop first */
|
||||
|
||||
offs = wcol->roundness * U.widget_unit;
|
||||
offs = wcol->roundness * BLI_rcti_size_y(rect);
|
||||
toffs = offs * 0.75f;
|
||||
round_box_edges(&wtb, roundboxalign, rect, offs);
|
||||
|
||||
|
@ -3712,7 +3732,7 @@ static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, i
|
|||
widget_init(&wtb);
|
||||
wtb.draw_outline = false;
|
||||
|
||||
rad = wcol->roundness * U.widget_unit;
|
||||
rad = wcol->roundness * BLI_rcti_size_y(rect);
|
||||
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
}
|
||||
|
@ -3885,7 +3905,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
|
|||
recttemp.xmax -= delta;
|
||||
recttemp.ymax -= delta;
|
||||
|
||||
rad = wcol->roundness * U.widget_unit;
|
||||
rad = wcol->roundness * BLI_rcti_size_y(&recttemp);
|
||||
round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
|
||||
|
||||
/* decoration */
|
||||
|
|
|
@ -2966,7 +2966,7 @@ void init_userdef_do_versions(void)
|
|||
btheme->tui.wcol_tool.roundness = 0.2f;
|
||||
btheme->tui.wcol_text.roundness = 0.2f;
|
||||
btheme->tui.wcol_radio.roundness = 0.2f;
|
||||
btheme->tui.wcol_option.roundness = 0.2f;
|
||||
btheme->tui.wcol_option.roundness = 0.333333f;
|
||||
btheme->tui.wcol_toggle.roundness = 0.25f;
|
||||
btheme->tui.wcol_num.roundness = 0.5f;
|
||||
btheme->tui.wcol_numslider.roundness = 0.5f;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_packedFile.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_screen.h"
|
||||
|
@ -113,7 +114,8 @@ void ED_editors_init(bContext *C)
|
|||
if (mode == OB_MODE_OBJECT) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
else if (!BKE_object_has_mode_data(ob, mode)) {
|
||||
/* For multi-edit mode we may already have mode data. */
|
||||
ID *data = ob->data;
|
||||
ob->mode = OB_MODE_OBJECT;
|
||||
if ((ob == obact) && !ID_IS_LINKED(ob) && !(data && ID_IS_LINKED(data))) {
|
||||
|
|
|
@ -63,7 +63,9 @@ void GPU_init(void)
|
|||
|
||||
gpu_batch_init();
|
||||
|
||||
immInit();
|
||||
if (!G.background) {
|
||||
immInit();
|
||||
}
|
||||
|
||||
GPU_pbvh_fix_linking();
|
||||
}
|
||||
|
@ -72,7 +74,9 @@ void GPU_init(void)
|
|||
|
||||
void GPU_exit(void)
|
||||
{
|
||||
immDestroy();
|
||||
if (!G.background) {
|
||||
immDestroy();
|
||||
}
|
||||
|
||||
gpu_batch_exit();
|
||||
|
||||
|
|
|
@ -68,8 +68,8 @@ const vec2 triavec[37] = vec2[37](
|
|||
vec2(-0.578579, 0.253369), vec2(-0.392773, 0.412794), vec2(-0.004241, -0.328551),
|
||||
vec2(-0.003001, 0.034320), vec2(1.055313, 0.864744), vec2(0.866408, 1.026895),
|
||||
/* ROUNDBOX_TRIA_HOLD_ACTION_ARROW - hold action arrows */
|
||||
#define OY -0.2
|
||||
#define SC 0.35
|
||||
#define OY (-0.2 / 2)
|
||||
#define SC (0.35 * 2)
|
||||
// vec2(-0.5 + SC, 1.0 + OY), vec2( 0.5, 1.0 + OY), vec2( 0.5, 0.0 + OY + SC),
|
||||
vec2( 0.5 - SC, 1.0 + OY), vec2(-0.5, 1.0 + OY), vec2(-0.5, 0.0 + OY + SC)
|
||||
#undef OY
|
||||
|
|
|
@ -483,6 +483,7 @@ enum {
|
|||
ID_RECALC_TRANSFORM = 1 << 5,
|
||||
ID_RECALC_COLLECTIONS = 1 << 6,
|
||||
ID_RECALC_COPY_ON_WRITE = 1 << 7,
|
||||
ID_RECALC_TIME = 1 << 8,
|
||||
/* Special flag to check if SOMETHING was changed. */
|
||||
ID_RECALC_ALL = (~(int)0),
|
||||
};
|
||||
|
|
|
@ -102,9 +102,11 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
|
|||
ArrayModifierData *amd = (ArrayModifierData *)md;
|
||||
if (amd->start_cap != NULL) {
|
||||
DEG_add_object_relation(ctx->node, amd->start_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier Start Cap");
|
||||
DEG_add_object_relation(ctx->node, amd->start_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier Start Cap");
|
||||
}
|
||||
if (amd->end_cap != NULL) {
|
||||
DEG_add_object_relation(ctx->node, amd->end_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier End Cap");
|
||||
DEG_add_object_relation(ctx->node, amd->end_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier End Cap");
|
||||
}
|
||||
if (amd->curve_ob) {
|
||||
struct Depsgraph *depsgraph = DEG_get_graph_from_handle(ctx->node);
|
||||
|
|
|
@ -93,6 +93,7 @@ void WM_main (struct bContext *C) ATTR_NORETURN;
|
|||
|
||||
void WM_init_splash (struct bContext *C);
|
||||
|
||||
void WM_init_opengl (void);
|
||||
|
||||
void WM_check (struct bContext *C);
|
||||
|
||||
|
|
|
@ -154,6 +154,40 @@ static void wm_free_reports(bContext *C)
|
|||
|
||||
bool wm_start_with_console = false; /* used in creator.c */
|
||||
|
||||
/**
|
||||
* Since we cannot know in advance if we will require the draw manager
|
||||
* context when starting blender in background mode (specially true with
|
||||
* scripts) we deferre the ghost initialization the most as possible
|
||||
* so that it does not break anything that can run in headless mode (as in
|
||||
* without display server attached).
|
||||
**/
|
||||
static bool opengl_is_init = false;
|
||||
|
||||
void WM_init_opengl(void)
|
||||
{
|
||||
/* must be called only once */
|
||||
BLI_assert(opengl_is_init == false);
|
||||
|
||||
if (G.background) {
|
||||
/* Ghost is still not init elsewhere in background mode. */
|
||||
wm_ghost_init(NULL);
|
||||
}
|
||||
|
||||
/* Needs to be first to have an ogl context bound. */
|
||||
DRW_opengl_context_create();
|
||||
|
||||
GPU_init();
|
||||
GPU_set_mipmap(true);
|
||||
GPU_set_linear_mipmap(true);
|
||||
GPU_set_anisotropic(U.anisotropic_filter);
|
||||
GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
|
||||
|
||||
#ifdef WITH_OPENSUBDIV
|
||||
BKE_subsurf_osd_init();
|
||||
#endif
|
||||
opengl_is_init = true;
|
||||
}
|
||||
|
||||
/* only called once, for startup */
|
||||
void WM_init(bContext *C, int argc, const char **argv)
|
||||
{
|
||||
|
@ -162,6 +196,7 @@ void WM_init(bContext *C, int argc, const char **argv)
|
|||
wm_ghost_init(C); /* note: it assigns C to ghost! */
|
||||
wm_init_cursor_data();
|
||||
}
|
||||
|
||||
GHOST_CreateSystemPaths();
|
||||
|
||||
BKE_addon_pref_type_init();
|
||||
|
@ -200,7 +235,6 @@ void WM_init(bContext *C, int argc, const char **argv)
|
|||
|
||||
/* get the default database, plus a wm */
|
||||
wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, NULL);
|
||||
|
||||
|
||||
BLT_lang_set(NULL);
|
||||
|
||||
|
@ -210,18 +244,7 @@ void WM_init(bContext *C, int argc, const char **argv)
|
|||
/* sets 3D mouse deadzone */
|
||||
WM_ndof_deadzone_set(U.ndof_deadzone);
|
||||
#endif
|
||||
DRW_opengl_context_create();
|
||||
|
||||
GPU_init();
|
||||
|
||||
GPU_set_mipmap(true);
|
||||
GPU_set_linear_mipmap(true);
|
||||
GPU_set_anisotropic(U.anisotropic_filter);
|
||||
GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
|
||||
|
||||
#ifdef WITH_OPENSUBDIV
|
||||
BKE_subsurf_osd_init();
|
||||
#endif
|
||||
WM_init_opengl();
|
||||
|
||||
UI_init();
|
||||
}
|
||||
|
@ -456,7 +479,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
|
|||
COM_deinitialize();
|
||||
#endif
|
||||
|
||||
if (!G.background) {
|
||||
if (opengl_is_init) {
|
||||
#ifdef WITH_OPENSUBDIV
|
||||
BKE_subsurf_osd_cleanup();
|
||||
#endif
|
||||
|
@ -483,7 +506,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
|
|||
|
||||
BLF_exit();
|
||||
|
||||
if (!G.background) {
|
||||
if (opengl_is_init) {
|
||||
GPU_pass_cache_free();
|
||||
DRW_opengl_context_destroy();
|
||||
}
|
||||
|
|
|
@ -1735,13 +1735,22 @@ void wm_window_testbreak(void)
|
|||
|
||||
/* **************** init ********************** */
|
||||
|
||||
/* bContext can be null in background mode because we don't
|
||||
* need to event handling. */
|
||||
void wm_ghost_init(bContext *C)
|
||||
{
|
||||
if (!g_system) {
|
||||
GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
|
||||
GHOST_EventConsumerHandle consumer;
|
||||
|
||||
if (C != NULL) {
|
||||
consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
|
||||
}
|
||||
|
||||
g_system = GHOST_CreateSystem();
|
||||
GHOST_AddEventConsumer(g_system, consumer);
|
||||
|
||||
if (C != NULL) {
|
||||
GHOST_AddEventConsumer(g_system, consumer);
|
||||
}
|
||||
|
||||
if (wm_init_state.native_pixels) {
|
||||
GHOST_UseNativePixels();
|
||||
|
|
Loading…
Reference in New Issue