Merge branch 'blender2.8' into blender2.8-workbench
This commit is contained in:
commit
ab10181d57
|
@ -3,22 +3,18 @@
|
|||
url = ../blender-addons.git
|
||||
branch = blender2.8
|
||||
ignore = all
|
||||
branch = master
|
||||
[submodule "release/scripts/addons_contrib"]
|
||||
path = release/scripts/addons_contrib
|
||||
url = ../blender-addons-contrib.git
|
||||
branch = master
|
||||
ignore = all
|
||||
branch = master
|
||||
[submodule "release/datafiles/locale"]
|
||||
path = release/datafiles/locale
|
||||
url = ../blender-translations.git
|
||||
branch = master
|
||||
ignore = all
|
||||
branch = master
|
||||
[submodule "source/tools"]
|
||||
path = source/tools
|
||||
url = ../blender-dev-tools.git
|
||||
branch = master
|
||||
ignore = all
|
||||
branch = master
|
||||
|
|
|
@ -123,6 +123,7 @@ class SelectCamera(Operator):
|
|||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
view = context.space_data
|
||||
if view.type == 'VIEW_3D' and not view.lock_camera_and_layers:
|
||||
camera = view.camera
|
||||
|
@ -136,8 +137,8 @@ class SelectCamera(Operator):
|
|||
else:
|
||||
if not self.extend:
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
scene.objects.active = camera
|
||||
camera.hide = False
|
||||
view_layer.objects.active = camera
|
||||
# camera.hide = False # XXX TODO where is this now?
|
||||
camera.select_set(action='SELECT')
|
||||
return {'FINISHED'}
|
||||
|
||||
|
@ -171,6 +172,7 @@ class SelectHierarchy(Operator):
|
|||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
select_new = []
|
||||
act_new = None
|
||||
|
||||
|
@ -206,7 +208,7 @@ class SelectHierarchy(Operator):
|
|||
for obj in select_new:
|
||||
obj.select_set(action='SELECT')
|
||||
|
||||
scene.objects.active = act_new
|
||||
view_layer.objects.active = act_new
|
||||
return {'FINISHED'}
|
||||
|
||||
return {'CANCELLED'}
|
||||
|
@ -881,171 +883,11 @@ class DupliOffsetFromCursor(Operator):
|
|||
return {'FINISHED'}
|
||||
|
||||
|
||||
class LodByName(Operator):
|
||||
"""Add levels of detail to this object based on object names"""
|
||||
bl_idname = "object.lod_by_name"
|
||||
bl_label = "Setup Levels of Detail By Name"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.active_object is not None)
|
||||
|
||||
def execute(self, context):
|
||||
ob = context.active_object
|
||||
|
||||
prefix = ""
|
||||
suffix = ""
|
||||
name = ""
|
||||
if ob.name.lower().startswith("lod0"):
|
||||
prefix = ob.name[:4]
|
||||
name = ob.name[4:]
|
||||
elif ob.name.lower().endswith("lod0"):
|
||||
name = ob.name[:-4]
|
||||
suffix = ob.name[-4:]
|
||||
else:
|
||||
return {'CANCELLED'}
|
||||
|
||||
level = 0
|
||||
while True:
|
||||
level += 1
|
||||
|
||||
if prefix:
|
||||
prefix = prefix[:3] + str(level)
|
||||
if suffix:
|
||||
suffix = suffix[:3] + str(level)
|
||||
|
||||
lod = None
|
||||
try:
|
||||
lod = bpy.data.objects[prefix + name + suffix]
|
||||
except KeyError:
|
||||
break
|
||||
|
||||
try:
|
||||
ob.lod_levels[level]
|
||||
except IndexError:
|
||||
bpy.ops.object.lod_add()
|
||||
|
||||
ob.lod_levels[level].object = lod
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class LodClearAll(Operator):
|
||||
"""Remove all levels of detail from this object"""
|
||||
bl_idname = "object.lod_clear_all"
|
||||
bl_label = "Clear All Levels of Detail"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.active_object is not None)
|
||||
|
||||
def execute(self, context):
|
||||
ob = context.active_object
|
||||
|
||||
if ob.lod_levels:
|
||||
while 'CANCELLED' not in bpy.ops.object.lod_remove():
|
||||
pass
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class LodGenerate(Operator):
|
||||
"""Generate levels of detail using the decimate modifier"""
|
||||
bl_idname = "object.lod_generate"
|
||||
bl_label = "Generate Levels of Detail"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
count = IntProperty(
|
||||
name="Count",
|
||||
default=3,
|
||||
)
|
||||
target = FloatProperty(
|
||||
name="Target Size",
|
||||
min=0.0, max=1.0,
|
||||
default=0.1,
|
||||
)
|
||||
package = BoolProperty(
|
||||
name="Package into Group",
|
||||
default=False,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.active_object is not None)
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
ob = scene.objects.active
|
||||
|
||||
lod_name = ob.name
|
||||
lod_suffix = "lod"
|
||||
lod_prefix = ""
|
||||
if lod_name.lower().endswith("lod0"):
|
||||
lod_suffix = lod_name[-3:-1]
|
||||
lod_name = lod_name[:-3]
|
||||
elif lod_name.lower().startswith("lod0"):
|
||||
lod_suffix = ""
|
||||
lod_prefix = lod_name[:3]
|
||||
lod_name = lod_name[4:]
|
||||
|
||||
group_name = lod_name.strip(' ._')
|
||||
if self.package:
|
||||
try:
|
||||
bpy.ops.object.group_link(group=group_name)
|
||||
except TypeError:
|
||||
bpy.ops.group.create(name=group_name)
|
||||
|
||||
step = (1.0 - self.target) / (self.count - 1)
|
||||
for i in range(1, self.count):
|
||||
scene.objects.active = ob
|
||||
bpy.ops.object.duplicate()
|
||||
lod = context.selected_objects[0]
|
||||
|
||||
scene.objects.active = ob
|
||||
bpy.ops.object.lod_add()
|
||||
scene.objects.active = lod
|
||||
|
||||
if lod_prefix:
|
||||
lod.name = lod_prefix + str(i) + lod_name
|
||||
else:
|
||||
lod.name = lod_name + lod_suffix + str(i)
|
||||
|
||||
lod.location.y = ob.location.y + 3.0 * i
|
||||
|
||||
if i == 1:
|
||||
modifier = lod.modifiers.new("lod_decimate", 'DECIMATE')
|
||||
else:
|
||||
modifier = lod.modifiers[-1]
|
||||
|
||||
modifier.ratio = 1.0 - step * i
|
||||
|
||||
ob.lod_levels[i].object = lod
|
||||
|
||||
if self.package:
|
||||
bpy.ops.object.group_link(group=group_name)
|
||||
lod.parent = ob
|
||||
|
||||
if self.package:
|
||||
for level in ob.lod_levels[1:]:
|
||||
level.object.hide = level.object.hide_render = True
|
||||
|
||||
lod.select_set(action='DESELECT')
|
||||
ob.select_set(action='SELECT')
|
||||
scene.objects.active = ob
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
classes = (
|
||||
ClearAllRestrictRender,
|
||||
DupliOffsetFromCursor,
|
||||
IsolateTypeRender,
|
||||
JoinUVs,
|
||||
LodByName,
|
||||
LodClearAll,
|
||||
LodGenerate,
|
||||
MakeDupliFace,
|
||||
SelectCamera,
|
||||
SelectHierarchy,
|
||||
|
|
|
@ -36,10 +36,10 @@ class GRAPH_HT_header(Header):
|
|||
row = layout.row(align=True)
|
||||
row.template_header()
|
||||
|
||||
GRAPH_MT_editor_menus.draw_collapsible(context, layout)
|
||||
|
||||
layout.prop(st, "mode", text="")
|
||||
|
||||
GRAPH_MT_editor_menus.draw_collapsible(context, layout)
|
||||
|
||||
dopesheet_filter(layout, context)
|
||||
|
||||
row = layout.row(align=True)
|
||||
|
|
|
@ -146,8 +146,9 @@ class TIME_MT_view(Menu):
|
|||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("time.view_all")
|
||||
layout.operator("time.view_frame")
|
||||
# NOTE: "action" now, since timeline is in the dopesheet editor, instead of as own editor
|
||||
layout.operator("action.view_all")
|
||||
layout.operator("action.view_frame")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
|
|
@ -133,8 +133,7 @@ class TOPBAR_HT_lower_bar(Header):
|
|||
|
||||
# Last Action (redo)
|
||||
layout.label("Last Action:")
|
||||
operators = context.window_manager.operators
|
||||
op = operators[-1] if operators else None
|
||||
op = context.active_operator
|
||||
row = layout.row()
|
||||
row.enabled = op is not None
|
||||
row.popover(
|
||||
|
|
|
@ -65,8 +65,11 @@ struct Icon {
|
|||
struct Icon_Geom {
|
||||
int icon_id;
|
||||
int coords_len;
|
||||
int coords_range[2];
|
||||
const unsigned char (*coords)[2];
|
||||
const unsigned char (*colors)[4];
|
||||
/* when not NULL, the memory of coords and colors is a sub-region of this pointer. */
|
||||
const void *mem;
|
||||
};
|
||||
|
||||
typedef struct Icon Icon;
|
||||
|
@ -84,8 +87,6 @@ int BKE_icon_id_ensure(struct ID *id);
|
|||
|
||||
int BKE_icon_preview_ensure(struct ID *id, struct PreviewImage *preview);
|
||||
|
||||
int BKE_icon_geom_ensure(struct Icon_Geom *geom);
|
||||
|
||||
/* retrieve icon for id */
|
||||
struct Icon *BKE_icon_get(const int icon_id);
|
||||
|
||||
|
@ -149,6 +150,10 @@ struct PreviewImage *BKE_previewimg_cached_thumbnail_read(
|
|||
void BKE_previewimg_cached_release(const char *name);
|
||||
void BKE_previewimg_cached_release_pointer(struct PreviewImage *prv);
|
||||
|
||||
int BKE_icon_geom_ensure(struct Icon_Geom *geom);
|
||||
struct Icon_Geom *BKE_icon_geom_from_memory(const uchar *data, size_t data_len);
|
||||
struct Icon_Geom *BKE_icon_geom_from_file(const char *filename);
|
||||
|
||||
struct ImBuf *BKE_icon_geom_rasterize(
|
||||
const struct Icon_Geom *geom,
|
||||
const unsigned int size_x, const unsigned int size_y);
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist_lockfree.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "BKE_icons.h"
|
||||
|
@ -96,8 +97,14 @@ static void icon_free(void *val)
|
|||
if (icon) {
|
||||
if (icon->obj_type == ICON_DATA_GEOM) {
|
||||
struct Icon_Geom *obj = icon->obj;
|
||||
MEM_freeN((void *)obj->coords);
|
||||
MEM_freeN((void *)obj->colors);
|
||||
if (obj->mem) {
|
||||
/* coords & colors are part of this memory. */
|
||||
MEM_freeN((void *)obj->mem);
|
||||
}
|
||||
else {
|
||||
MEM_freeN((void *)obj->coords);
|
||||
MEM_freeN((void *)obj->colors);
|
||||
}
|
||||
MEM_freeN(icon->obj);
|
||||
}
|
||||
|
||||
|
@ -621,22 +628,6 @@ int BKE_icon_preview_ensure(ID *id, PreviewImage *preview)
|
|||
return preview->icon_id;
|
||||
}
|
||||
|
||||
int BKE_icon_geom_ensure(struct Icon_Geom *geom)
|
||||
{
|
||||
BLI_assert(BLI_thread_is_main());
|
||||
|
||||
if (geom->icon_id) {
|
||||
return geom->icon_id;
|
||||
}
|
||||
|
||||
geom->icon_id = get_next_free_id();
|
||||
|
||||
icon_create(geom->icon_id, ICON_DATA_GEOM, geom);
|
||||
/* Not managed for now, we may want this to be configurable per icon). */
|
||||
|
||||
return geom->icon_id;
|
||||
}
|
||||
|
||||
Icon *BKE_icon_get(const int icon_id)
|
||||
{
|
||||
BLI_assert(BLI_thread_is_main());
|
||||
|
@ -735,3 +726,73 @@ bool BKE_icon_delete_unmanaged(const int icon_id)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Geometry Icon
|
||||
* \{ */
|
||||
|
||||
int BKE_icon_geom_ensure(struct Icon_Geom *geom)
|
||||
{
|
||||
BLI_assert(BLI_thread_is_main());
|
||||
|
||||
if (geom->icon_id) {
|
||||
return geom->icon_id;
|
||||
}
|
||||
|
||||
geom->icon_id = get_next_free_id();
|
||||
|
||||
icon_create(geom->icon_id, ICON_DATA_GEOM, geom);
|
||||
/* Not managed for now, we may want this to be configurable per icon). */
|
||||
|
||||
return geom->icon_id;
|
||||
}
|
||||
|
||||
struct Icon_Geom *BKE_icon_geom_from_memory(const uchar *data, size_t data_len)
|
||||
{
|
||||
BLI_assert(BLI_thread_is_main());
|
||||
if (data_len <= 8) {
|
||||
goto fail;
|
||||
}
|
||||
const int div = 3 * 2 * 3;
|
||||
const int coords_len = (data_len - 8) / div;
|
||||
if (coords_len * div != data_len) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
const uchar header[4] = {'V', 'C', 'O', 0};
|
||||
const uchar *p = data;
|
||||
if (memcmp(p, header, ARRAY_SIZE(header)) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
p += 4;
|
||||
|
||||
struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__);
|
||||
geom->coords_range[0] = (int)*p++;
|
||||
geom->coords_range[1] = (int)*p++;
|
||||
/* x, y ignored for now */
|
||||
p += 2;
|
||||
|
||||
geom->coords_len = coords_len;
|
||||
geom->coords = (const void *)p;
|
||||
geom->colors = (const void *)(p + (data_len / 3));
|
||||
geom->icon_id = 0;
|
||||
geom->mem = data;
|
||||
return geom;
|
||||
|
||||
fail:
|
||||
MEM_freeN((void *)data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct Icon_Geom *BKE_icon_geom_from_file(const char *filename)
|
||||
{
|
||||
BLI_assert(BLI_thread_is_main());
|
||||
size_t data_len;
|
||||
uchar *data = BLI_file_read_binary_as_mem(filename, 0, &data_len);
|
||||
if (data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return BKE_icon_geom_from_memory(data, data_len);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -134,7 +134,9 @@ static void do_version_area_change_space_to_space_action(ScrArea *area, const Sc
|
|||
/* Different defaults for timeline */
|
||||
region_channels = BKE_area_find_region_type(area, RGN_TYPE_CHANNELS);
|
||||
region_channels->flag |= RGN_FLAG_HIDDEN;
|
||||
|
||||
saction->mode = SACTCONT_TIMELINE;
|
||||
saction->ads.flag |= ADS_FLAG_SUMMARY_COLLAPSED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -656,30 +658,33 @@ void do_versions_after_linking_280(Main *main)
|
|||
const wmWindowManager *wm = main->wm.first;
|
||||
const Scene *scene = main->scene.first;
|
||||
|
||||
/* Action editors need a scene for creation. First, update active
|
||||
* screens using the active scene of the window they're displayed in.
|
||||
* Next, update remaining screens using first scene in main listbase. */
|
||||
if (wm != NULL) {
|
||||
/* Action editors need a scene for creation. First, update active
|
||||
* screens using the active scene of the window they're displayed in.
|
||||
* Next, update remaining screens using first scene in main listbase. */
|
||||
|
||||
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
||||
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
|
||||
for (ScrArea *area = screen->areabase.first; area; area = area->next) {
|
||||
if (ELEM(area->butspacetype, SPACE_TIME, SPACE_LOGIC)) {
|
||||
do_version_area_change_space_to_space_action(area, win->scene);
|
||||
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
||||
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
|
||||
for (ScrArea *area = screen->areabase.first; area; area = area->next) {
|
||||
if (ELEM(area->butspacetype, SPACE_TIME, SPACE_LOGIC)) {
|
||||
do_version_area_change_space_to_space_action(area, win->scene);
|
||||
|
||||
/* Don't forget to unset! */
|
||||
area->butspacetype = SPACE_EMPTY;
|
||||
/* Don't forget to unset! */
|
||||
area->butspacetype = SPACE_EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scene != NULL) {
|
||||
for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
|
||||
for (ScrArea *area = screen->areabase.first; area; area = area->next) {
|
||||
if (ELEM(area->butspacetype, SPACE_TIME, SPACE_LOGIC)) {
|
||||
/* Areas that were already handled won't be handled again */
|
||||
do_version_area_change_space_to_space_action(area, scene);
|
||||
|
||||
for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
|
||||
for (ScrArea *area = screen->areabase.first; area; area = area->next) {
|
||||
if (ELEM(area->butspacetype, SPACE_TIME, SPACE_LOGIC)) {
|
||||
/* Areas that were already handled won't be handled again */
|
||||
do_version_area_change_space_to_space_action(area, scene);
|
||||
|
||||
/* Don't forget to unset! */
|
||||
area->butspacetype = SPACE_EMPTY;
|
||||
/* Don't forget to unset! */
|
||||
area->butspacetype = SPACE_EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,9 @@ typedef enum eDepsgraph_Tag {
|
|||
/* Only inform editors about the change. Don't modify datablock itself. */
|
||||
DEG_TAG_EDITORS_UPDATE = (1 << 12),
|
||||
} eDepsgraph_Tag;
|
||||
|
||||
const char *DEG_update_tag_as_string(eDepsgraph_Tag flag);
|
||||
|
||||
void DEG_id_tag_update(struct ID *id, int flag);
|
||||
void DEG_id_tag_update_ex(struct Main *bmain, struct ID *id, int flag);
|
||||
|
||||
|
|
|
@ -241,13 +241,14 @@ bool DepsgraphRelationBuilder::has_node(const OperationKey &key) const
|
|||
return find_node(key) != NULL;
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc,
|
||||
DepsNode *node_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
DepsRelation *DepsgraphRelationBuilder::add_time_relation(
|
||||
TimeSourceDepsNode *timesrc,
|
||||
DepsNode *node_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
if (timesrc && node_to) {
|
||||
graph_->add_new_relation(timesrc, node_to, description, check_unique);
|
||||
return graph_->add_new_relation(timesrc, node_to, description, check_unique);
|
||||
}
|
||||
else {
|
||||
DEG_DEBUG_PRINTF(BUILD, "add_time_relation(%p = %s, %p = %s, %s) Failed\n",
|
||||
|
@ -255,16 +256,20 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc,
|
|||
node_to, (node_to) ? node_to->identifier().c_str() : "<None>",
|
||||
description);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::add_operation_relation(
|
||||
DepsRelation *DepsgraphRelationBuilder::add_operation_relation(
|
||||
OperationDepsNode *node_from,
|
||||
OperationDepsNode *node_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
if (node_from && node_to) {
|
||||
graph_->add_new_relation(node_from, node_to, description, check_unique);
|
||||
return graph_->add_new_relation(node_from,
|
||||
node_to,
|
||||
description,
|
||||
check_unique);
|
||||
}
|
||||
else {
|
||||
DEG_DEBUG_PRINTF(BUILD, "add_operation_relation(%p = %s, %p = %s, %s) Failed\n",
|
||||
|
@ -272,6 +277,7 @@ void DepsgraphRelationBuilder::add_operation_relation(
|
|||
node_to, (node_to) ? node_to->identifier().c_str() : "<None>",
|
||||
description);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::add_collision_relations(
|
||||
|
@ -419,6 +425,8 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
|
|||
build_object_flags(base, object);
|
||||
/* Parenting. */
|
||||
if (object->parent != NULL) {
|
||||
/* Make sure parent object's relations are built. */
|
||||
build_object(NULL, object->parent);
|
||||
/* Parent relationship. */
|
||||
build_object_parent(object);
|
||||
/* Local -> parent. */
|
||||
|
@ -2007,6 +2015,9 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node
|
|||
/* All dangling operations should also be executed after copy-on-write. */
|
||||
GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, comp_node->operations_map)
|
||||
{
|
||||
if (op_node == op_entry) {
|
||||
continue;
|
||||
}
|
||||
if (op_node->inlinks.size() == 0) {
|
||||
graph_->add_new_relation(op_cow, op_node, "CoW Dependency");
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace DEG {
|
|||
struct Depsgraph;
|
||||
struct DepsNode;
|
||||
struct DepsNodeHandle;
|
||||
struct DepsRelation;
|
||||
struct RootDepsNode;
|
||||
struct IDDepsNode;
|
||||
struct TimeSourceDepsNode;
|
||||
|
@ -176,22 +177,22 @@ struct DepsgraphRelationBuilder
|
|||
void begin_build();
|
||||
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
void add_relation(const KeyFrom& key_from,
|
||||
const KeyTo& key_to,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
DepsRelation *add_relation(const KeyFrom& key_from,
|
||||
const KeyTo& key_to,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
template <typename KeyTo>
|
||||
void add_relation(const TimeSourceKey& key_from,
|
||||
const KeyTo& key_to,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
DepsRelation *add_relation(const TimeSourceKey& key_from,
|
||||
const KeyTo& key_to,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
template <typename KeyType>
|
||||
void add_node_handle_relation(const KeyType& key_from,
|
||||
const DepsNodeHandle *handle,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
DepsRelation *add_node_handle_relation(const KeyType& key_from,
|
||||
const DepsNodeHandle *handle,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
void build_view_layer(Scene *scene, ViewLayer *view_layer);
|
||||
void build_group(Object *object, Group *group);
|
||||
|
@ -280,14 +281,14 @@ protected:
|
|||
OperationDepsNode *find_node(const OperationKey &key) const;
|
||||
bool has_node(const OperationKey &key) const;
|
||||
|
||||
void add_time_relation(TimeSourceDepsNode *timesrc,
|
||||
DepsNode *node_to,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
void add_operation_relation(OperationDepsNode *node_from,
|
||||
OperationDepsNode *node_to,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
DepsRelation *add_time_relation(TimeSourceDepsNode *timesrc,
|
||||
DepsNode *node_to,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
DepsRelation *add_operation_relation(OperationDepsNode *node_from,
|
||||
OperationDepsNode *node_to,
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
template <typename KeyType>
|
||||
DepsNodeHandle create_node_handle(const KeyType& key,
|
||||
|
|
|
@ -46,17 +46,17 @@ OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType&
|
|||
}
|
||||
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
|
||||
const KeyTo &key_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
DepsRelation *DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
|
||||
const KeyTo &key_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
DepsNode *node_from = get_node(key_from);
|
||||
DepsNode *node_to = get_node(key_to);
|
||||
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
|
||||
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
|
||||
if (op_from && op_to) {
|
||||
add_operation_relation(op_from, op_to, description, check_unique);
|
||||
return add_operation_relation(op_from, op_to, description, check_unique);
|
||||
}
|
||||
else {
|
||||
if (!op_from) {
|
||||
|
@ -78,24 +78,27 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
|
|||
description, key_to.identifier().c_str());
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename KeyTo>
|
||||
void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from,
|
||||
const KeyTo &key_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
DepsRelation *DepsgraphRelationBuilder::add_relation(
|
||||
const TimeSourceKey &key_from,
|
||||
const KeyTo &key_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
TimeSourceDepsNode *time_from = get_node(key_from);
|
||||
DepsNode *node_to = get_node(key_to);
|
||||
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
|
||||
if (time_from != NULL && op_to != NULL) {
|
||||
add_time_relation(time_from, op_to, description, check_unique);
|
||||
return add_time_relation(time_from, op_to, description, check_unique);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
void DepsgraphRelationBuilder::add_node_handle_relation(
|
||||
DepsRelation *DepsgraphRelationBuilder::add_node_handle_relation(
|
||||
const KeyType &key_from,
|
||||
const DepsNodeHandle *handle,
|
||||
const char *description,
|
||||
|
@ -105,7 +108,7 @@ void DepsgraphRelationBuilder::add_node_handle_relation(
|
|||
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
|
||||
OperationDepsNode *op_to = handle->node->get_entry_operation();
|
||||
if (op_from != NULL && op_to != NULL) {
|
||||
add_operation_relation(op_from, op_to, description, check_unique);
|
||||
return add_operation_relation(op_from, op_to, description, check_unique);
|
||||
}
|
||||
else {
|
||||
if (!op_from) {
|
||||
|
@ -117,6 +120,7 @@ void DepsgraphRelationBuilder::add_node_handle_relation(
|
|||
description, key_from.identifier().c_str());
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
|
|
|
@ -259,6 +259,18 @@ static void deg_debug_graphviz_relation_color(const DebugContext &ctx,
|
|||
deg_debug_fprintf(ctx, "%s", color);
|
||||
}
|
||||
|
||||
static void deg_debug_graphviz_relation_style(const DebugContext &ctx,
|
||||
const DepsRelation *rel)
|
||||
{
|
||||
const char *style_default = "solid";
|
||||
const char *style_no_flush = "dashed";
|
||||
const char *style = style_default;
|
||||
if (rel->flag & DEPSREL_FLAG_NO_FLUSH) {
|
||||
style = style_no_flush;
|
||||
}
|
||||
deg_debug_fprintf(ctx, "%s", style);
|
||||
}
|
||||
|
||||
static void deg_debug_graphviz_node_style(const DebugContext &ctx, const DepsNode *node)
|
||||
{
|
||||
const char *base_style = "filled"; /* default style */
|
||||
|
@ -468,16 +480,23 @@ static void deg_debug_graphviz_node_relations(const DebugContext &ctx,
|
|||
/* Note: without label an id seem necessary to avoid bugs in graphviz/dot */
|
||||
deg_debug_fprintf(ctx, "id=\"%s\"", rel->name);
|
||||
// deg_debug_fprintf(ctx, "label=\"%s\"", rel->name);
|
||||
deg_debug_fprintf(ctx, ",color="); deg_debug_graphviz_relation_color(ctx, rel);
|
||||
deg_debug_fprintf(ctx, ",color=");
|
||||
deg_debug_graphviz_relation_color(ctx, rel);
|
||||
deg_debug_fprintf(ctx, ",style=");
|
||||
deg_debug_graphviz_relation_style(ctx, rel);
|
||||
deg_debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth);
|
||||
/* NOTE: edge from node to own cluster is not possible and gives graphviz
|
||||
* warning, avoid this here by just linking directly to the invisible
|
||||
* placeholder node
|
||||
*/
|
||||
if (deg_debug_graphviz_is_cluster(tail) && !deg_debug_graphviz_is_owner(head, tail)) {
|
||||
if (deg_debug_graphviz_is_cluster(tail) &&
|
||||
!deg_debug_graphviz_is_owner(head, tail))
|
||||
{
|
||||
deg_debug_fprintf(ctx, ",ltail=\"cluster_%p\"", tail);
|
||||
}
|
||||
if (deg_debug_graphviz_is_cluster(head) && !deg_debug_graphviz_is_owner(tail, head)) {
|
||||
if (deg_debug_graphviz_is_cluster(head) &&
|
||||
!deg_debug_graphviz_is_owner(tail, head))
|
||||
{
|
||||
deg_debug_fprintf(ctx, ",lhead=\"cluster_%p\"", head);
|
||||
}
|
||||
deg_debug_fprintf(ctx, "];" NL);
|
||||
|
|
|
@ -236,6 +236,11 @@ static bool pointer_to_component_node_criteria(
|
|||
*type = DEG_NODE_TYPE_SHADING;
|
||||
return true;
|
||||
}
|
||||
else if (ptr->type == &RNA_Curve) {
|
||||
*id = (ID *)ptr->id.data;
|
||||
*type = DEG_NODE_TYPE_GEOMETRY;
|
||||
return true;
|
||||
}
|
||||
if (prop != NULL) {
|
||||
/* All unknown data effectively falls under "parameter evaluation". */
|
||||
if (RNA_property_is_idprop(prop)) {
|
||||
|
|
|
@ -64,13 +64,12 @@ struct OperationDepsNode;
|
|||
|
||||
/* Settings/Tags on Relationship */
|
||||
typedef enum eDepsRelation_Flag {
|
||||
/* "touched" tag is used when filtering, to know which to collect */
|
||||
DEPSREL_FLAG_TEMP_TAG = (1 << 0),
|
||||
|
||||
/* "cyclic" link - when detecting cycles, this relationship was the one
|
||||
* which triggers a cyclic relationship to exist in the graph
|
||||
* which triggers a cyclic relationship to exist in the graph.
|
||||
*/
|
||||
DEPSREL_FLAG_CYCLIC = (1 << 1),
|
||||
DEPSREL_FLAG_CYCLIC = (1 << 0),
|
||||
/* Update flush will not go through this relation. */
|
||||
DEPSREL_FLAG_NO_FLUSH = (1 << 1),
|
||||
} eDepsRelation_Flag;
|
||||
|
||||
/* B depends on A (A -> B) */
|
||||
|
|
|
@ -473,10 +473,64 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
|
|||
}
|
||||
}
|
||||
|
||||
string stringify_append_bit(const string& str, eDepsgraph_Tag tag)
|
||||
{
|
||||
string result = str;
|
||||
if (!result.empty()) {
|
||||
result += ", ";
|
||||
}
|
||||
result += DEG_update_tag_as_string(tag);
|
||||
return result;
|
||||
}
|
||||
|
||||
string stringify_update_bitfield(int flag)
|
||||
{
|
||||
if (flag == 0) {
|
||||
return "LEGACY_0";
|
||||
}
|
||||
string result = "";
|
||||
int current_flag = flag;
|
||||
/* Special cases to avoid ALL flags form being split into
|
||||
* individual bits.
|
||||
*/
|
||||
if ((current_flag & DEG_TAG_PSYS_ALL) == DEG_TAG_PSYS_ALL) {
|
||||
result = stringify_append_bit(result, DEG_TAG_PSYS_ALL);
|
||||
}
|
||||
/* Handle all the rest of the flags. */
|
||||
while (current_flag != 0) {
|
||||
eDepsgraph_Tag tag =
|
||||
(eDepsgraph_Tag)(1 << bitscan_forward_clear_i(¤t_flag));
|
||||
result = stringify_append_bit(result, tag);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
} // namespace DEG
|
||||
|
||||
const char *DEG_update_tag_as_string(eDepsgraph_Tag flag)
|
||||
{
|
||||
switch (flag) {
|
||||
case DEG_TAG_TRANSFORM: return "TRANSFORM";
|
||||
case DEG_TAG_GEOMETRY: return "GEOMETRY";
|
||||
case DEG_TAG_TIME: return "TIME";
|
||||
case DEG_TAG_PSYS_REDO: return "PSYS_REDO";
|
||||
case DEG_TAG_PSYS_RESET: return "PSYS_RESET";
|
||||
case DEG_TAG_PSYS_TYPE: return "PSYS_TYPE";
|
||||
case DEG_TAG_PSYS_CHILD: return "PSYS_CHILD";
|
||||
case DEG_TAG_PSYS_PHYS: return "PSYS_PHYS";
|
||||
case DEG_TAG_PSYS_ALL: return "PSYS_ALL";
|
||||
case DEG_TAG_COPY_ON_WRITE: return "COPY_ON_WRITE";
|
||||
case DEG_TAG_SHADING_UPDATE: return "SHADING_UPDATE";
|
||||
case DEG_TAG_SELECT_UPDATE: return "SELECT_UPDATE";
|
||||
case DEG_TAG_BASE_FLAGS_UPDATE: return "BASE_FLAGS_UPDATE";
|
||||
case DEG_TAG_EDITORS_UPDATE: return "EDITORS_UPDATE";
|
||||
}
|
||||
BLI_assert(!"Unhandled update flag, should never happen!");
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
/* Data-Based Tagging */
|
||||
|
||||
/* Tag given ID for an update in all the dependency graphs. */
|
||||
|
@ -492,7 +546,10 @@ void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag)
|
|||
return;
|
||||
}
|
||||
if (G.debug & G_DEBUG_DEPSGRAPH_TAG) {
|
||||
printf("%s: id=%s flag=%d\n", __func__, id->name, flag);
|
||||
printf("%s: id=%s flags=%s\n",
|
||||
__func__,
|
||||
id->name,
|
||||
DEG::stringify_update_bitfield(flag).c_str());
|
||||
}
|
||||
DEG::deg_id_tag_update(bmain, id, flag);
|
||||
}
|
||||
|
|
|
@ -182,6 +182,9 @@ BLI_INLINE OperationDepsNode *flush_schedule_children(
|
|||
{
|
||||
OperationDepsNode *result = NULL;
|
||||
foreach (DepsRelation *rel, op_node->outlinks) {
|
||||
if (rel->flag & DEPSREL_FLAG_NO_FLUSH) {
|
||||
continue;
|
||||
}
|
||||
OperationDepsNode *to_node = (OperationDepsNode *)rel->to;
|
||||
if (to_node->scheduled == false) {
|
||||
if (result != NULL) {
|
||||
|
|
|
@ -652,19 +652,24 @@ void DRW_draw_cursor(void)
|
|||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glLineWidth(1.0f);
|
||||
|
||||
if (is_cursor_visible(draw_ctx, scene, view_layer)) {
|
||||
int co[2];
|
||||
if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
|
||||
|
||||
ED_region_pixelspace(ar);
|
||||
gpuTranslate2f(co[0], co[1]);
|
||||
gpuTranslate2f(co[0] + 0.5f, co[1] + 0.5f);
|
||||
gpuScale2f(U.widget_unit, U.widget_unit);
|
||||
|
||||
Gwn_Batch *cursor_batch = DRW_cache_cursor_get();
|
||||
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR);
|
||||
GWN_batch_program_set(cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
|
||||
|
||||
/* Draw nice Anti Aliased cursor. */
|
||||
glLineWidth(1.0f);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
GWN_batch_draw(cursor_batch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,9 +307,6 @@ static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend)
|
|||
if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE))
|
||||
return;
|
||||
|
||||
/* XXX old cruft! use notifiers instead */
|
||||
//select_actionchannel_by_name (ob->action, bone->name, !(shift));
|
||||
|
||||
if (extend)
|
||||
bone->flag &= ~BONE_SELECTED;
|
||||
else
|
||||
|
@ -381,7 +378,7 @@ void POSE_OT_select_linked(wmOperatorType *ot)
|
|||
ot->idname = "POSE_OT_select_linked";
|
||||
ot->description = "Select bones related to selected ones by parent/child relationships";
|
||||
|
||||
/* api callbacks */
|
||||
/* callbacks */
|
||||
/* leave 'exec' unset */
|
||||
ot->invoke = pose_select_connected_invoke;
|
||||
ot->poll = pose_select_linked_poll;
|
||||
|
|
|
@ -758,6 +758,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
|
|||
void (*clear_func)(bPoseChannel *), const char default_ksName[])
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bool changed_multi = false;
|
||||
|
||||
/* sanity checks */
|
||||
if (ELEM(NULL, clear_func, default_ksName)) {
|
||||
|
@ -765,17 +766,15 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
bool changed_multi = false;
|
||||
|
||||
/* only clear relevant transforms for selected bones */
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob_iter) {
|
||||
|
||||
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob_iter)
|
||||
{
|
||||
ListBase dsources = {NULL, NULL};
|
||||
|
||||
bool changed = false;
|
||||
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
|
||||
|
||||
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan)
|
||||
{
|
||||
/* run provided clearing function */
|
||||
clear_func(pchan);
|
||||
changed = true;
|
||||
|
@ -795,7 +794,8 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
|
|||
pchan->bone->flag |= BONE_UNKEYED;
|
||||
}
|
||||
}
|
||||
} FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
|
||||
}
|
||||
FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
|
||||
|
||||
if (changed) {
|
||||
changed_multi = true;
|
||||
|
@ -821,7 +821,8 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
|
|||
/* note, notifier might evolve */
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob_iter);
|
||||
}
|
||||
} FOREACH_OBJECT_IN_MODE_END;
|
||||
}
|
||||
FOREACH_OBJECT_IN_MODE_END;
|
||||
|
||||
return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
||||
}
|
||||
|
@ -916,57 +917,61 @@ void POSE_OT_transforms_clear(wmOperatorType *ot)
|
|||
|
||||
static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
|
||||
float cframe = (float)CFRA;
|
||||
const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
|
||||
|
||||
if ((ob->adt) && (ob->adt->action)) {
|
||||
/* XXX: this is just like this to avoid contaminating anything else;
|
||||
* just pose values should change, so this should be fine
|
||||
*/
|
||||
bPose *dummyPose = NULL;
|
||||
Object workob = {{NULL}};
|
||||
bPoseChannel *pchan;
|
||||
|
||||
/* execute animation step for current frame using a dummy copy of the pose */
|
||||
BKE_pose_copy_data(&dummyPose, ob->pose, 0);
|
||||
|
||||
BLI_strncpy(workob.id.name, "OB<ClearTfmWorkOb>", sizeof(workob.id.name));
|
||||
workob.type = OB_ARMATURE;
|
||||
workob.data = ob->data;
|
||||
workob.adt = ob->adt;
|
||||
workob.pose = dummyPose;
|
||||
|
||||
BKE_animsys_evaluate_animdata(scene, &workob.id, workob.adt, cframe, ADT_RECALC_ANIM);
|
||||
|
||||
/* copy back values, but on selected bones only */
|
||||
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
pose_bone_do_paste(ob, pchan, only_select, 0);
|
||||
}
|
||||
|
||||
/* free temp data - free manually as was copied without constraints */
|
||||
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->prop) {
|
||||
IDP_FreeProperty(pchan->prop);
|
||||
MEM_freeN(pchan->prop);
|
||||
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob)
|
||||
{
|
||||
if ((ob->adt) && (ob->adt->action)) {
|
||||
/* XXX: this is just like this to avoid contaminating anything else;
|
||||
* just pose values should change, so this should be fine
|
||||
*/
|
||||
bPose *dummyPose = NULL;
|
||||
Object workob = {{NULL}};
|
||||
bPoseChannel *pchan;
|
||||
|
||||
/* execute animation step for current frame using a dummy copy of the pose */
|
||||
BKE_pose_copy_data(&dummyPose, ob->pose, 0);
|
||||
|
||||
BLI_strncpy(workob.id.name, "OB<ClearTfmWorkOb>", sizeof(workob.id.name));
|
||||
workob.type = OB_ARMATURE;
|
||||
workob.data = ob->data;
|
||||
workob.adt = ob->adt;
|
||||
workob.pose = dummyPose;
|
||||
|
||||
BKE_animsys_evaluate_animdata(scene, &workob.id, workob.adt, cframe, ADT_RECALC_ANIM);
|
||||
|
||||
/* copy back values, but on selected bones only */
|
||||
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
pose_bone_do_paste(ob, pchan, only_select, 0);
|
||||
}
|
||||
|
||||
/* free temp data - free manually as was copied without constraints */
|
||||
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->prop) {
|
||||
IDP_FreeProperty(pchan->prop);
|
||||
MEM_freeN(pchan->prop);
|
||||
}
|
||||
}
|
||||
|
||||
/* was copied without constraints */
|
||||
BLI_freelistN(&dummyPose->chanbase);
|
||||
MEM_freeN(dummyPose);
|
||||
}
|
||||
else {
|
||||
/* no animation, so just reset whole pose to rest pose
|
||||
* (cannot just restore for selected though)
|
||||
*/
|
||||
BKE_pose_rest(ob->pose);
|
||||
}
|
||||
|
||||
/* was copied without constraints */
|
||||
BLI_freelistN(&dummyPose->chanbase);
|
||||
MEM_freeN(dummyPose);
|
||||
/* notifiers and updates */
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
|
||||
}
|
||||
else {
|
||||
/* no animation, so just reset whole pose to rest pose
|
||||
* (cannot just restore for selected though)
|
||||
*/
|
||||
BKE_pose_rest(ob->pose);
|
||||
}
|
||||
|
||||
/* notifiers and updates */
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
|
||||
FOREACH_OBJECT_IN_MODE_END;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
|
@ -6777,6 +6777,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||
|
||||
if (but->flag & UI_BUT_OVERRIDEN) {
|
||||
if (is_array_component) {
|
||||
#if 0 /* Disabled for now. */
|
||||
ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
|
||||
uiItemFullO_ptr(layout, ot, "Overrides Type", ICON_NONE,
|
||||
NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
|
||||
|
@ -6784,17 +6785,18 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||
uiItemFullO_ptr(layout, ot, "Single Override Type", ICON_NONE,
|
||||
NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
|
||||
RNA_boolean_set(&op_ptr, "all", false);
|
||||
|
||||
#endif
|
||||
uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Overrides"),
|
||||
ICON_X, "UI_OT_override_remove_button", "all", true);
|
||||
uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Single Override"),
|
||||
ICON_X, "UI_OT_override_remove_button", "all", false);
|
||||
}
|
||||
else {
|
||||
#if 0 /* Disabled for now. */
|
||||
uiItemFullO(layout, "UI_OT_override_type_set_button", "Override Type", ICON_NONE,
|
||||
NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
|
||||
RNA_boolean_set(&op_ptr, "all", false);
|
||||
|
||||
#endif
|
||||
uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Override"),
|
||||
ICON_X, "UI_OT_override_remove_button", "all", true);
|
||||
}
|
||||
|
|
|
@ -540,7 +540,12 @@ static int override_type_set_button_exec(bContext *C, wmOperator *op)
|
|||
|
||||
static int override_type_set_button_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
#if 0 /* Disabled for now */
|
||||
return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
|
||||
#else
|
||||
RNA_enum_set(op->ptr, "type", IDOVERRIDESTATIC_OP_REPLACE);
|
||||
return override_type_set_button_exec(C, op);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void UI_OT_override_type_set_button(wmOperatorType *ot)
|
||||
|
@ -562,7 +567,7 @@ static void UI_OT_override_type_set_button(wmOperatorType *ot)
|
|||
RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
|
||||
ot->prop = RNA_def_enum(ot->srna, "type", override_type_items, UIOverride_Type_Replace,
|
||||
"Type", "Type of override operation");
|
||||
/* TODO: add itemf callback, not all aoptions are available for all data types... */
|
||||
/* TODO: add itemf callback, not all options are available for all data types... */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -136,9 +136,11 @@ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
|
|||
}
|
||||
else {
|
||||
/* get */
|
||||
for (but = block->buttons.first; but; but = but->next)
|
||||
if (ui_popup_string_hash(but->str) == mem[hash_mod])
|
||||
for (but = block->buttons.first; but; but = but->next) {
|
||||
if (ui_popup_string_hash(but->str) == mem[hash_mod]) {
|
||||
return but;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -176,9 +178,8 @@ struct uiPopupMenu {
|
|||
static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
|
||||
{
|
||||
uiBlock *block;
|
||||
uiBut *bt;
|
||||
uiPopupMenu *pup = arg_pup;
|
||||
int offset[2], minwidth, width, height;
|
||||
int minwidth, width, height;
|
||||
char direction;
|
||||
bool flip;
|
||||
|
||||
|
@ -218,8 +219,9 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||
|
||||
/* in some cases we create the block before the region,
|
||||
* so we set it delayed here if necessary */
|
||||
if (BLI_findindex(&handle->region->uiblocks, block) == -1)
|
||||
if (BLI_findindex(&handle->region->uiblocks, block) == -1) {
|
||||
UI_block_region_set(block, handle->region);
|
||||
}
|
||||
|
||||
block->direction = direction;
|
||||
|
||||
|
@ -228,6 +230,9 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||
UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
|
||||
|
||||
if (pup->popup) {
|
||||
uiBut *bt;
|
||||
int offset[2];
|
||||
|
||||
uiBut *but_activate = NULL;
|
||||
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
|
||||
UI_block_direction_set(block, direction);
|
||||
|
@ -251,8 +256,9 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||
/* position mouse at 0.8*width of the button and below the tile
|
||||
* on the first item */
|
||||
offset[0] = 0;
|
||||
for (bt = block->buttons.first; bt; bt = bt->next)
|
||||
for (bt = block->buttons.first; bt; bt = bt->next) {
|
||||
offset[0] = min_ii(offset[0], -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect)));
|
||||
}
|
||||
|
||||
offset[1] = 2.1 * UI_UNIT_Y;
|
||||
|
||||
|
@ -292,8 +298,9 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||
}
|
||||
|
||||
/* if menu slides out of other menu, override direction */
|
||||
if (pup->slideout)
|
||||
if (pup->slideout) {
|
||||
UI_block_direction_set(block, UI_DIR_RIGHT);
|
||||
}
|
||||
|
||||
return pup->block;
|
||||
}
|
||||
|
@ -334,8 +341,9 @@ uiPopupBlockHandle *ui_popup_menu_create(
|
|||
pup->block->flag |= UI_BLOCK_NO_FLIP;
|
||||
}
|
||||
#endif
|
||||
if (but->context)
|
||||
if (but->context) {
|
||||
uiLayoutContextCopy(pup->layout, but->context);
|
||||
}
|
||||
}
|
||||
|
||||
/* menu is created from a callback */
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
* - UI is not constrained to a list.
|
||||
* - Pressing a button won't close the pop-over.
|
||||
* - Different draw style (to show this is has different behavior from a menu).
|
||||
* - #PanelType are used insetead of #MenuType.
|
||||
* - #PanelType are used instead of #MenuType.
|
||||
* - No menu flipping support.
|
||||
* - No moving the menu to fit the mouse cursor.
|
||||
* - No key accelerators to access menu items
|
||||
|
@ -46,38 +46,23 @@
|
|||
* - No title.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "interface_intern.h"
|
||||
#include "interface_regions_intern.h"
|
||||
|
||||
|
@ -102,7 +87,7 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
|
|||
{
|
||||
uiBlock *block;
|
||||
uiPopover *pup = arg_pup;
|
||||
int offset[2], minwidth, width, height;
|
||||
int minwidth, width, height;
|
||||
|
||||
if (pup->menu_func) {
|
||||
pup->block->handle = handle;
|
||||
|
@ -134,6 +119,7 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
|
|||
const int block_margin = U.widget_unit / 2;
|
||||
|
||||
if (pup->popover) {
|
||||
int offset[2] = {0, 0}; /* Dummy. */
|
||||
UI_block_flag_enable(block, UI_BLOCK_LOOP);
|
||||
UI_block_direction_set(block, block->direction);
|
||||
block->minbounds = minwidth;
|
||||
|
@ -182,8 +168,9 @@ uiPopupBlockHandle *ui_popover_panel_create(
|
|||
* reverse some enum's but not others, so reverse all so the first menu
|
||||
* items are always close to the mouse cursor */
|
||||
else {
|
||||
if (but->context)
|
||||
if (but->context) {
|
||||
uiLayoutContextCopy(pup->layout, but->context);
|
||||
}
|
||||
}
|
||||
|
||||
/* menu is created from a callback */
|
||||
|
@ -221,7 +208,9 @@ uiPopover *UI_popover_begin_ex(bContext *C, const char *block_name)
|
|||
uiPopover *pup = MEM_callocN(sizeof(uiPopover), "popover menu");
|
||||
|
||||
pup->block = UI_block_begin(C, NULL, block_name, UI_EMBOSS);
|
||||
pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 0, MENU_PADDING, style);
|
||||
pup->layout = UI_block_layout(
|
||||
pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0,
|
||||
U.widget_unit * UI_POPOVER_WIDTH_UNITS, 0, MENU_PADDING, style);
|
||||
|
||||
/* Copied from menus, change if needed. */
|
||||
uiLayoutSetOperatorContext(pup->layout, WM_OP_EXEC_REGION_WIN);
|
||||
|
@ -282,6 +271,6 @@ uiLayout *UI_popover_layout(uiPopover *pup)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* We may want to support this in futurew */
|
||||
/* We may want to support this in future */
|
||||
/* Similar to UI_popup_menu_invoke */
|
||||
// int UI_popover_panel_invoke(bContext *C, const char *idname, ReportList *reports);
|
||||
|
|
|
@ -2730,7 +2730,7 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
static void widget_popover_back(uiWidgetColors *wcol, rcti *rect, int flag, int direction)
|
||||
static void widget_popover_back(uiWidgetColors *wcol, rcti *rect, int UNUSED(flag), int direction)
|
||||
{
|
||||
/* tsk, this isn't nice. */
|
||||
const float unit_half = (BLI_rcti_size_x(rect) / UI_POPOVER_WIDTH_UNITS) / 2;
|
||||
|
@ -2738,22 +2738,46 @@ static void widget_popover_back(uiWidgetColors *wcol, rcti *rect, int flag, int
|
|||
rect->ymax -= unit_half;
|
||||
rect->ymin += unit_half;
|
||||
|
||||
widget_menu_back(wcol, rect, flag, direction);
|
||||
|
||||
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
|
||||
immUniformColor4ubv((unsigned char *)wcol->inner);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
immBegin(GWN_PRIM_TRIS, 3);
|
||||
immVertex2f(pos, cent_x - unit_half, rect->ymax);
|
||||
immVertex2f(pos, cent_x + unit_half, rect->ymax);
|
||||
immVertex2f(pos, cent_x, rect->ymax + unit_half);
|
||||
immEnd();
|
||||
|
||||
/* Extracted from 'widget_menu_back', keep separate to avoid menu changes breaking popovers */
|
||||
{
|
||||
uiWidgetBase wtb;
|
||||
widget_init(&wtb);
|
||||
|
||||
const int roundboxalign = UI_CNR_ALL;
|
||||
widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit);
|
||||
|
||||
round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit);
|
||||
wtb.draw_emboss = false;
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
}
|
||||
|
||||
/* Draw popover arrow (top/bottom) */
|
||||
if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) {
|
||||
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
immUniformColor4ubv((unsigned char *)wcol->inner);
|
||||
glEnable(GL_BLEND);
|
||||
immBegin(GWN_PRIM_TRIS, 3);
|
||||
if (direction == UI_DIR_DOWN) {
|
||||
const float y = rect->ymax;
|
||||
immVertex2f(pos, cent_x - unit_half, y);
|
||||
immVertex2f(pos, cent_x + unit_half, y);
|
||||
immVertex2f(pos, cent_x, y + unit_half);
|
||||
}
|
||||
else {
|
||||
const float y = rect->ymin;
|
||||
immVertex2f(pos, cent_x - unit_half, y);
|
||||
immVertex2f(pos, cent_x + unit_half, rect->ymin);
|
||||
immVertex2f(pos, cent_x, y - unit_half);
|
||||
}
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void ui_hsv_cursor(float x, float y)
|
||||
|
@ -4293,7 +4317,7 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
|
|||
}
|
||||
|
||||
/* align with open menu */
|
||||
if (but->active) {
|
||||
if (but->active && (but->type != UI_BTYPE_POPOVER)) {
|
||||
int direction = ui_but_menu_direction(but);
|
||||
|
||||
if (direction == UI_DIR_UP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT);
|
||||
|
|
|
@ -261,10 +261,6 @@ void OBJECT_OT_grouped_select(struct wmOperatorType *ot);
|
|||
void OBJECT_OT_bake_image(wmOperatorType *ot);
|
||||
void OBJECT_OT_bake(wmOperatorType *ot);
|
||||
|
||||
/* object_lod.c */
|
||||
void OBJECT_OT_lod_add(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_lod_remove(struct wmOperatorType *ot);
|
||||
|
||||
/* object_random.c */
|
||||
void TRANSFORM_OT_vertex_random(struct wmOperatorType *ot);
|
||||
|
||||
|
|
|
@ -660,13 +660,6 @@ static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea
|
|||
return;
|
||||
}
|
||||
|
||||
/* can't click on bottom corners on OS X, already used for resizing */
|
||||
#ifdef __APPLE__
|
||||
if (!(sa->totrct.xmin == 0 && sa->totrct.ymin == 0) || WM_window_is_fullscreen(win))
|
||||
#else
|
||||
(void)win;
|
||||
#endif
|
||||
|
||||
float coords[4][4] = {
|
||||
/* Bottom-left. */
|
||||
{sa->totrct.xmin,
|
||||
|
@ -690,6 +683,17 @@ static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea
|
|||
sa->totrct.ymax - (AZONESPOT - 1)}};
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
/* can't click on bottom corners on OS X, already used for resizing */
|
||||
#ifdef __APPLE__
|
||||
if (!WM_window_is_fullscreen(win) &&
|
||||
((coords[i][0] == 0 && coords[i][1] == 0) ||
|
||||
(coords[i][0] == WM_window_pixels_x(win) && coords[i][1] == 0))) {
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
(void)win;
|
||||
#endif
|
||||
|
||||
/* set area action zones */
|
||||
az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
|
||||
BLI_addtail(&(sa->actionzones), az);
|
||||
|
|
|
@ -286,9 +286,9 @@ static void drawscredge_corner(ScrArea *sa, int sizex, int sizey)
|
|||
/* Bottom-Left. */
|
||||
drawscredge_corner_geometry(sizex, sizey,
|
||||
sa->v1->vec.x,
|
||||
sa->v1->vec.y,
|
||||
sa->v1->vec.x + size,
|
||||
sa->v1->vec.y + size,
|
||||
sa->v1->vec.y,
|
||||
sa->v1->vec.x + size,
|
||||
sa->v1->vec.y + size,
|
||||
M_PI_2 * 2.0f,
|
||||
color);
|
||||
|
||||
|
|
|
@ -277,6 +277,7 @@ static void animrecord_check_state(Scene *scene, ID *id, wmTimer *animtimer)
|
|||
/* if playback has just looped around, we need to add a new NLA track+strip to allow a clean pass to occur */
|
||||
if ((sad) && (sad->flag & ANIMPLAY_FLAG_JUMPED)) {
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
const bool is_first = (adt) && (adt->nla_tracks.first == NULL);
|
||||
|
||||
/* perform push-down manually with some differences
|
||||
* NOTE: BKE_nla_action_pushdown() sync warning...
|
||||
|
@ -297,6 +298,29 @@ static void animrecord_check_state(Scene *scene, ID *id, wmTimer *animtimer)
|
|||
strip->extendmode = NLASTRIP_EXTEND_NOTHING;
|
||||
strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS | NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_ACTIVE);
|
||||
|
||||
/* copy current "action blending" settings from adt to the strip,
|
||||
* as it was keyframed with these settings, so omitting them will
|
||||
* change the effect [T54766]
|
||||
*/
|
||||
if (is_first == false) {
|
||||
strip->blendmode = adt->act_blendmode;
|
||||
strip->influence = adt->act_influence;
|
||||
|
||||
if (adt->act_influence < 1.0f) {
|
||||
/* enable "user-controlled" influence (which will insert a default keyframe)
|
||||
* so that the influence doesn't get lost on the new update
|
||||
*
|
||||
* NOTE: An alternative way would have been to instead hack the influence
|
||||
* to not get always get reset to full strength if NLASTRIP_FLAG_USR_INFLUENCE
|
||||
* is disabled but auto-blending isn't being used. However, that approach
|
||||
* is a bit hacky/hard to discover, and may cause backwards compatability issues,
|
||||
* so it's better to just do it this way.
|
||||
*/
|
||||
strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
|
||||
BKE_nlastrip_validate_fcurves(strip);
|
||||
}
|
||||
}
|
||||
|
||||
/* also, adjust the AnimData's action extend mode to be on
|
||||
* 'nothing' so that previous result still play
|
||||
*/
|
||||
|
|
|
@ -7506,19 +7506,21 @@ bool RNA_struct_override_matches(
|
|||
continue;
|
||||
}
|
||||
|
||||
#if 0 /* This actually makes things slower, since it has to check for animation paths etc! */
|
||||
if (RNA_property_animated(ptr_local, prop_local)) {
|
||||
/* We cannot do anything here really, animation is some kind of dynamic overrides that has
|
||||
* precedence over static one... */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define RNA_PATH_BUFFSIZE 8192
|
||||
#define RNA_PATH_PRINTF(_str, ...) \
|
||||
if (BLI_snprintf(rna_path, RNA_PATH_BUFFSIZE, \
|
||||
(_str), __VA_ARGS__) >= RNA_PATH_BUFFSIZE) \
|
||||
{ rna_path = BLI_sprintfN((_str), __VA_ARGS__); }(void)0
|
||||
if (BLI_snprintf(rna_path, RNA_PATH_BUFFSIZE, \
|
||||
(_str), __VA_ARGS__) >= RNA_PATH_BUFFSIZE) \
|
||||
{ rna_path = BLI_sprintfN((_str), __VA_ARGS__); }(void)0
|
||||
#define RNA_PATH_FREE \
|
||||
if (rna_path != rna_path_buffer) MEM_freeN(rna_path)
|
||||
if (rna_path != rna_path_buffer) MEM_freeN(rna_path)
|
||||
|
||||
char rna_path_buffer[RNA_PATH_BUFFSIZE];
|
||||
char *rna_path = rna_path_buffer;
|
||||
|
|
|
@ -2484,10 +2484,12 @@ void RNA_def_constraint(BlenderRNA *brna)
|
|||
/* flags */
|
||||
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_OFF);
|
||||
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_ui_text(prop, "Disable", "Enable/Disable Constraint");
|
||||
|
||||
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_EXPAND);
|
||||
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_ui_text(prop, "Expanded", "Constraint's panel is expanded in UI");
|
||||
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
|
||||
|
||||
|
|
|
@ -4922,12 +4922,13 @@ void RNA_def_modifier(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "show_viewport", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Realtime);
|
||||
RNA_def_property_ui_text(prop, "Realtime", "Display modifier in viewport");
|
||||
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION | PROP_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 0);
|
||||
|
||||
prop = RNA_def_property(srna, "show_render", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Render);
|
||||
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_ui_text(prop, "Render", "Use modifier during render");
|
||||
RNA_def_property_ui_icon(prop, ICON_SCENE, 0);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL);
|
||||
|
@ -4946,6 +4947,7 @@ void RNA_def_modifier(BlenderRNA *brna)
|
|||
|
||||
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Expanded);
|
||||
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_ui_text(prop, "Expanded", "Set modifier expanded in the user interface");
|
||||
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
|
||||
|
||||
|
|
|
@ -2073,6 +2073,7 @@ static void rna_def_object(BlenderRNA *brna)
|
|||
/* constraints */
|
||||
prop = RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Constraint");
|
||||
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_ui_text(prop, "Constraints", "Constraints affecting the transformation of the object");
|
||||
/* RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "constraints__add", "constraints__remove"); */
|
||||
rna_def_object_constraints(brna, prop);
|
||||
|
|
|
@ -97,7 +97,7 @@ static void rna_Object_select_set(Object *ob, bContext *C, ReportList *reports,
|
|||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
|
||||
if (!base) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, view_layer->name);
|
||||
BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ static void rna_Pose_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRN
|
|||
/* XXX when to use this? ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); */
|
||||
|
||||
DEG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_POSE, ptr->id.data);
|
||||
}
|
||||
|
||||
static void rna_Pose_IK_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
|
@ -805,6 +806,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
|
|||
/* Bone Constraints */
|
||||
prop = RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Constraint");
|
||||
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_ui_text(prop, "Constraints", "Constraints that act on this PoseChannel");
|
||||
|
||||
rna_def_pose_channel_constraints(brna, prop);
|
||||
|
|
|
@ -1160,14 +1160,6 @@ static int rna_property_override_diff_propptr(
|
|||
}
|
||||
}
|
||||
|
||||
static char *rna_path_collection_prop_item_extend(const char *rna_path_prop, const char *item_name)
|
||||
{
|
||||
const size_t esc_item_name_len = strlen(item_name) * 2;
|
||||
char *esc_item_name = alloca(sizeof(*esc_item_name) * esc_item_name_len);
|
||||
BLI_strescape(esc_item_name, item_name, esc_item_name_len);
|
||||
return BLI_sprintfN("%s[\"%s\"]", rna_path_prop, esc_item_name);
|
||||
}
|
||||
|
||||
int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
|
||||
PropertyRNA *prop_a, PropertyRNA *prop_b,
|
||||
const int len_a, const int len_b,
|
||||
|
@ -1300,7 +1292,6 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
|
|||
|
||||
case PROP_FLOAT:
|
||||
{
|
||||
const bool is_proportional = (prop_a->flag & PROP_PROPORTIONAL) != 0;
|
||||
if (len_a) {
|
||||
float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
|
||||
float *array_a, *array_b;
|
||||
|
@ -1320,7 +1311,7 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
|
|||
|
||||
if (op != NULL && created) {
|
||||
BKE_override_static_property_operation_get(
|
||||
op, is_proportional ? IDOVERRIDESTATIC_OP_MULTIPLY : IDOVERRIDESTATIC_OP_REPLACE,
|
||||
op, IDOVERRIDESTATIC_OP_REPLACE,
|
||||
NULL, NULL, -1, -1, true, NULL, NULL);
|
||||
if (r_override_changed) {
|
||||
*r_override_changed = created;
|
||||
|
@ -1347,7 +1338,7 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
|
|||
|
||||
if (op != NULL && created) { /* If not yet overridden... */
|
||||
BKE_override_static_property_operation_get(
|
||||
op, is_proportional ? IDOVERRIDESTATIC_OP_MULTIPLY : IDOVERRIDESTATIC_OP_REPLACE,
|
||||
op, IDOVERRIDESTATIC_OP_REPLACE,
|
||||
NULL, NULL, -1, -1, true, NULL, NULL);
|
||||
if (r_override_changed) {
|
||||
*r_override_changed = created;
|
||||
|
@ -1437,8 +1428,6 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
|
|||
for (; iter_a.valid && iter_b.valid;
|
||||
RNA_property_collection_next(&iter_a), RNA_property_collection_next(&iter_b), idx++)
|
||||
{
|
||||
char *extended_rna_path = NULL;
|
||||
|
||||
if (iter_a.ptr.type != iter_b.ptr.type) {
|
||||
/* nothing we can do (for until we support adding/removing from collections), skip it. */
|
||||
equals = false;
|
||||
|
@ -1459,6 +1448,18 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
|
|||
propname_a = RNA_property_string_get_alloc(&iter_a.ptr, propname, propname_buff_a, sizeof(propname_buff_a), NULL);
|
||||
propname_b = RNA_property_string_get_alloc(&iter_b.ptr, propname, propname_buff_b, sizeof(propname_buff_b), NULL);
|
||||
}
|
||||
|
||||
#define RNA_PATH_BUFFSIZE 8192
|
||||
#define RNA_PATH_PRINTF(_str, ...) \
|
||||
if (BLI_snprintf(extended_rna_path_buffer, RNA_PATH_BUFFSIZE, \
|
||||
(_str), __VA_ARGS__) >= RNA_PATH_BUFFSIZE) \
|
||||
{ extended_rna_path = BLI_sprintfN((_str), __VA_ARGS__); }(void)0
|
||||
#define RNA_PATH_FREE \
|
||||
if (extended_rna_path != extended_rna_path_buffer) MEM_freeN(extended_rna_path)
|
||||
|
||||
char extended_rna_path_buffer[RNA_PATH_BUFFSIZE];
|
||||
char *extended_rna_path = extended_rna_path_buffer;
|
||||
|
||||
/* There may be a propname defined in some cases, while no actual name set
|
||||
* (e.g. happens with point cache), in that case too we want to fall back to index. */
|
||||
if ((propname_a != NULL && propname_a[0] != '\0') || (propname_b != NULL && propname_b[0] != '\0')) {
|
||||
|
@ -1467,12 +1468,14 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
|
|||
equals = false;
|
||||
}
|
||||
else if (rna_path) {
|
||||
extended_rna_path = rna_path_collection_prop_item_extend(rna_path, propname_a);
|
||||
char esc_item_name[RNA_PATH_BUFFSIZE];
|
||||
BLI_strescape(esc_item_name, propname_a, RNA_PATH_BUFFSIZE);
|
||||
RNA_PATH_PRINTF("%s[\"%s\"]", rna_path, esc_item_name);
|
||||
}
|
||||
}
|
||||
else { /* Based on index... */
|
||||
if (rna_path) {
|
||||
extended_rna_path = BLI_sprintfN("%s[%d]", rna_path, idx);
|
||||
RNA_PATH_PRINTF("%s[%d]", rna_path, idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1490,11 +1493,15 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
|
|||
if (propname_b != propname_buff_b) {
|
||||
MEM_SAFE_FREE(propname_b);
|
||||
}
|
||||
MEM_SAFE_FREE(extended_rna_path);
|
||||
RNA_PATH_FREE;
|
||||
|
||||
if (!rna_path && !equals) {
|
||||
break; /* Early out in case we do not want to loop over whole collection. */
|
||||
}
|
||||
|
||||
#undef RNA_PATH_BUFFSIZE
|
||||
#undef RNA_PATH_PRINTF
|
||||
#undef RNA_PATH_FREE
|
||||
}
|
||||
|
||||
equals = equals && !(iter_a.valid || iter_b.valid); /* Not same number of items in both collections... */
|
||||
|
|
|
@ -38,22 +38,28 @@
|
|||
|
||||
/* We may want to load direct from file. */
|
||||
PyDoc_STRVAR(bpy_app_icons_new_triangles_doc,
|
||||
".. function:: new_triangles(coords, colors)"
|
||||
".. function:: new_triangles(range, coords, colors)"
|
||||
"\n"
|
||||
" Create a new icon from triangle geometry.\n"
|
||||
"\n"
|
||||
" :arg range: Pair of ints.\n"
|
||||
" :type range: tuple.\n"
|
||||
" :arg coords: Sequence of bytes (6 floats for one triangle) for (X, Y) coordinates.\n"
|
||||
" :type coords: byte sequence\n"
|
||||
" :type coords: byte sequence.\n"
|
||||
" :arg colors: Sequence of ints (12 for one triangles) for RGBA.\n"
|
||||
" :type colors: byte sequence\n"
|
||||
" :type colors: byte sequence.\n"
|
||||
" :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
|
||||
" :rtype: int\n"
|
||||
);
|
||||
static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
/* bytes */
|
||||
uchar coords_range[2];
|
||||
PyObject *py_coords, *py_colors;
|
||||
if (!PyArg_ParseTuple(args, "SS:new_triangles", &py_coords, &py_colors)) {
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "(BB)SS:new_triangles",
|
||||
&coords_range[0], &coords_range[1], &py_coords, &py_colors))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -78,6 +84,8 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a
|
|||
|
||||
struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__);
|
||||
geom->coords_len = tris_len;
|
||||
geom->coords_range[0] = coords_range[0];
|
||||
geom->coords_range[1] = coords_range[1];
|
||||
geom->coords = coords;
|
||||
geom->colors = colors;
|
||||
geom->icon_id = 0;
|
||||
|
@ -85,6 +93,36 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a
|
|||
return PyLong_FromLong(icon_id);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_icons_new_triangles_from_file_doc,
|
||||
".. function:: new_triangles_from_file(filename)"
|
||||
"\n"
|
||||
" Create a new icon from triangle geometry.\n"
|
||||
"\n"
|
||||
" :arg range: File path.\n"
|
||||
" :type range: string.\n"
|
||||
" :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
|
||||
" :rtype: int\n"
|
||||
);
|
||||
static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
/* bytes */
|
||||
char *filename;
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "s:new_triangles_from_file",
|
||||
&filename))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct Icon_Geom *geom = BKE_icon_geom_from_file(filename);
|
||||
if (geom == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "Unable to load from file");
|
||||
return NULL;
|
||||
}
|
||||
int icon_id = BKE_icon_geom_ensure(geom);
|
||||
return PyLong_FromLong(icon_id);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_icons_release_doc,
|
||||
".. function:: release(icon_id)"
|
||||
"\n"
|
||||
|
@ -110,6 +148,7 @@ static PyObject *bpy_app_icons_release(PyObject *UNUSED(self), PyObject *args)
|
|||
|
||||
static struct PyMethodDef M_AppIcons_methods[] = {
|
||||
{"new_triangles", (PyCFunction)bpy_app_icons_new_triangles, METH_VARARGS, bpy_app_icons_new_triangles_doc},
|
||||
{"new_triangles_from_file", (PyCFunction)bpy_app_icons_new_triangles_from_file, METH_VARARGS, bpy_app_icons_new_triangles_from_file_doc},
|
||||
{"release", (PyCFunction)bpy_app_icons_release, METH_VARARGS, bpy_app_icons_release_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
|
|
@ -1953,13 +1953,14 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
|
|||
int action = WM_HANDLER_CONTINUE;
|
||||
|
||||
switch (val) {
|
||||
case EVT_FILESELECT_FULL_OPEN:
|
||||
case EVT_FILESELECT_FULL_OPEN:
|
||||
{
|
||||
ScrArea *sa;
|
||||
|
||||
/* sa can be null when window A is active, but mouse is over window B */
|
||||
/* in this case, open file select in original window A */
|
||||
if (handler->op_area == NULL) {
|
||||
|
||||
/* sa can be null when window A is active, but mouse is over window B
|
||||
* in this case, open file select in original window A. Also don't
|
||||
* use global areas. */
|
||||
if (handler->op_area == NULL || ED_area_is_global(handler->op_area)) {
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
sa = (ScrArea *)screen->areabase.first;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f35d8e55afffb9da50cc13b14615ed280f9e558c
|
||||
Subproject commit 56f3887596b538a9fc17e0439883f2e2305f2633
|
Loading…
Reference in New Issue