Merge branch 'blender2.8' into blender2.8-workbench

This commit is contained in:
Jeroen Bakker 2018-04-26 07:52:09 +02:00
commit e4ee23f780
67 changed files with 605 additions and 319 deletions

View File

@ -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);

View File

@ -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

View File

@ -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 ""

View File

@ -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')),
),
),
],
}

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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");

View File

@ -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

View File

@ -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(&deg_graph->scene->id);
if (need_on_visible_update) {
DEG_graph_on_visible_update(bmain, graph);
}

View File

@ -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(&deg_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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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))

View File

@ -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;
}

View File

@ -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. */

View File

@ -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)

View File

@ -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);

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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))) {

View File

@ -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();

View File

@ -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

View File

@ -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),
};

View File

@ -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);

View File

@ -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);

View File

@ -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();
}

View File

@ -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();