Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-03-04 17:32:05 +01:00
commit de2625518b
50 changed files with 172 additions and 103 deletions

View File

@ -646,6 +646,11 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
[NSApp setDelegate:appDelegate];
}
// AppKit provides automatic window tabbing. Blender is a single-tabbed application without a
// macOS tab bar, and should explicitly opt-out of this. This is also controlled by the macOS
// user default #NSWindowTabbingEnabled.
NSWindow.allowsAutomaticWindowTabbing = NO;
[NSApp finishLaunching];
[pool drain];

View File

@ -31,8 +31,6 @@ extern "C" {
#endif
struct CryptomatteSession;
struct ID;
struct Main;
struct Material;
struct Object;
struct RenderResult;

View File

@ -21,7 +21,6 @@
#endif
struct Mesh;
struct VolumeGrid;
namespace blender::bke {

View File

@ -514,7 +514,7 @@ static void studiolight_create_matcap_gputexture(StudioLightImage *sli)
ImBuf *ibuf = sli->ibuf;
float *gpu_matcap_3components = MEM_callocN(sizeof(float[3]) * ibuf->x * ibuf->y, __func__);
float(*offset4)[4] = (float(*)[4])ibuf->rect_float;
const float(*offset4)[4] = (const float(*)[4])ibuf->rect_float;
float(*offset3)[3] = (float(*)[3])gpu_matcap_3components;
for (int i = 0; i < ibuf->x * ibuf->y; i++, offset4++, offset3++) {
copy_v3_v3(*offset3, *offset4);

View File

@ -377,7 +377,7 @@ int BLI_exists(const char *path)
struct stat st;
BLI_assert(!BLI_path_is_rel(path));
if (stat(path, &st)) {
return (0);
return 0;
}
#endif
return (st.st_mode);

View File

@ -27,7 +27,6 @@
/* Forward declarations. */
struct RenderResult;
struct StampData;
/* Cryptomatte includes hash in its meta data keys. The hash is generated from the render
* layer/pass name. Compositing happens without the knowledge of the original layer and pass. The

View File

@ -304,5 +304,8 @@ vec3 probe_evaluate_grid(GridData gd, vec3 P, vec3 N, vec3 localpos)
vec3 probe_evaluate_world_diff(vec3 N)
{
if (prbNumRenderGrid == 0) {
return vec3(0);
}
return irradiance_from_cell_get(0, N);
}

View File

@ -935,8 +935,15 @@ GPUVertBuf *DRW_cache_object_pos_vertbuf_get(Object *ob)
int DRW_cache_object_material_count_get(struct Object *ob)
{
short type = ob->type;
Mesh *me = BKE_object_get_evaluated_mesh(ob);
short type = (me != NULL) ? OB_MESH : ob->type;
if (me != NULL && type != OB_POINTCLOUD) {
/* Some object types (e.g. curves) can have a Curve in ob->data, but will be rendered as mesh.
* For point clouds this never happens. Ideally this check would happen at another level and we
* would just have to care about ob->data here. */
type = OB_MESH;
}
switch (type) {
case OB_MESH:

View File

@ -305,6 +305,7 @@ static void fmodifier_frame_range_draw(const bContext *C, Panel *panel)
PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
FModifier *fcm = (FModifier *)ptr->data;
uiLayoutSetActive(layout, fcm->flag & FMODIFIER_FLAG_RANGERESTRICT);
@ -478,6 +479,7 @@ static void fn_generator_panel_draw(const bContext *C, Panel *panel)
uiItemR(layout, ptr, "function_type", 0, "", ICON_NONE);
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "use_additive", 0, NULL, ICON_NONE);
@ -698,6 +700,7 @@ static void envelope_panel_draw(const bContext *C, Panel *panel)
FMod_Envelope *env = (FMod_Envelope *)fcm->data;
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
/* General settings. */
col = uiLayoutColumn(layout, true);
@ -792,6 +795,7 @@ static void limits_panel_draw(const bContext *C, Panel *panel)
PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
/* Minimums. */
col = uiLayoutColumn(layout, false);
@ -853,6 +857,7 @@ static void stepped_panel_draw(const bContext *C, Panel *panel)
PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
/* Stepping Settings. */
col = uiLayoutColumn(layout, false);

View File

@ -2093,7 +2093,7 @@ static void annotation_draw_apply_event(
p->mval[1] = (float)event->mval[1] - y;
/* Key to toggle stabilization. */
if (event->shift > 0 && p->paintmode == GP_PAINTMODE_DRAW) {
if (event->shift && p->paintmode == GP_PAINTMODE_DRAW) {
/* Using permanent stabilization, shift will deactivate the flag. */
if (p->flags & GP_PAINTFLAG_USE_STABILIZER) {
if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) {
@ -2108,7 +2108,7 @@ static void annotation_draw_apply_event(
}
}
/* verify key status for straight lines */
else if ((event->ctrl > 0) || (event->alt > 0)) {
else if (event->ctrl || event->alt) {
if (p->straight[0] == 0) {
int dx = abs((int)(p->mval[0] - p->mvalo[0]));
int dy = abs((int)(p->mval[1] - p->mvalo[1]));
@ -2348,7 +2348,7 @@ static int annotation_draw_invoke(bContext *C, wmOperator *op, const wmEvent *ev
p->flags |= GP_PAINTFLAG_USE_STABILIZER | GP_PAINTFLAG_USE_STABILIZER_TEMP;
annotation_draw_toggle_stabilizer_cursor(p, true);
}
else if (event->shift > 0) {
else if (event->shift) {
p->flags |= GP_PAINTFLAG_USE_STABILIZER_TEMP;
annotation_draw_toggle_stabilizer_cursor(p, true);
}

View File

@ -131,7 +131,7 @@ void GPENCIL_OT_stroke_enter_editcurve_mode(wmOperatorType *ot)
"Error Threshold",
"Threshold on the maximum deviation from the actual stroke",
FLT_MIN,
10.f);
10.0f);
RNA_def_property_ui_range(prop, FLT_MIN, 10.0f, 0.1f, 5);
}

View File

@ -2835,7 +2835,7 @@ static void gpencil_draw_apply_event(bContext *C,
/* verify direction for straight lines and guides */
if ((is_speed_guide) ||
((event->alt > 0) && (RNA_boolean_get(op->ptr, "disable_straight") == false))) {
(event->alt && (RNA_boolean_get(op->ptr, "disable_straight") == false))) {
if (p->straight == 0) {
int dx = (int)fabsf(p->mval[0] - p->mvali[0]);
int dy = (int)fabsf(p->mval[1] - p->mvali[1]);
@ -2876,13 +2876,13 @@ static void gpencil_draw_apply_event(bContext *C,
/* special eraser modes */
if (p->paintmode == GP_PAINTMODE_ERASER) {
if (event->shift > 0) {
if (event->shift) {
p->flags |= GP_PAINTFLAG_HARD_ERASER;
}
else {
p->flags &= ~GP_PAINTFLAG_HARD_ERASER;
}
if (event->alt > 0) {
if (event->alt) {
p->flags |= GP_PAINTFLAG_STROKE_ERASER;
}
else {

View File

@ -55,7 +55,6 @@ struct FModifier;
struct bAction;
struct uiBlock;
struct uiLayout;
struct PointerRNA;
struct PropertyRNA;

View File

@ -52,7 +52,6 @@ struct rcti;
struct uiBlock;
struct uiLayout;
struct wmKeyConfig;
struct wmMsgBus;
struct wmMsgSubscribeKey;
struct wmMsgSubscribeValue;
struct wmNotifier;

View File

@ -120,7 +120,7 @@ void UI_draw_roundbox_4fv_ex(const rctf *rect,
};
GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
GPU_batch_uniform_4fv_array(batch, "parameters", 11, (const float(*)[4]) & widget_params);
GPU_blend(GPU_BLEND_ALPHA);
GPU_batch_draw(batch);
GPU_blend(GPU_BLEND_NONE);
@ -2376,7 +2376,7 @@ void ui_draw_dropshadow(
GPUBatch *batch = ui_batch_roundbox_shadow_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW);
GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float(*)[4]) & widget_params);
GPU_batch_uniform_4fv_array(batch, "parameters", 4, (const float(*)[4]) & widget_params);
GPU_batch_uniform_1f(batch, "alpha", 1.0f - visibility);
GPU_batch_draw(batch);

View File

@ -168,12 +168,14 @@ static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEve
#define PIE_MENU_INTERVAL 0.01
#define BUTTON_AUTO_OPEN_THRESH 0.2
#define BUTTON_MOUSE_TOWARDS_THRESH 1.0
/* pixels to move the cursor to get out of keyboard navigation */
/** Pixels to move the cursor to get out of keyboard navigation. */
#define BUTTON_KEYNAV_PX_LIMIT 8
#define MENU_TOWARDS_MARGIN 20 /* margin in pixels */
#define MENU_TOWARDS_WIGGLE_ROOM 64 /* tolerance in pixels */
/* drag-lock distance threshold in pixels */
/** Margin around the menu, use to check if we're moving towards this rectangle (in pixels). */
#define MENU_TOWARDS_MARGIN 20
/** Tolerance for closing menus (in pixels). */
#define MENU_TOWARDS_WIGGLE_ROOM 64
/** Drag-lock distance threshold (in pixels). */
#define BUTTON_DRAGLOCK_THRESH 3
typedef enum uiButtonActivateType {

View File

@ -1180,7 +1180,7 @@ void UI_widgetbase_draw_cache_flush(void)
/* draw single */
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(
batch, "parameters", MAX_WIDGET_PARAMETERS, (float(*)[4])g_widget_base_batch.params);
batch, "parameters", MAX_WIDGET_PARAMETERS, (const float(*)[4])g_widget_base_batch.params);
GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
GPU_batch_draw(batch);
}

View File

@ -966,7 +966,7 @@ static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd)
float planes[4][4];
planes_from_projmat(
(float(*)[4])kcd->projmat, planes[2], planes[0], planes[3], planes[1], NULL, NULL);
(const float(*)[4])kcd->projmat, planes[2], planes[0], planes[3], planes[1], NULL, NULL);
/* ray-cast all planes */
{

View File

@ -4172,15 +4172,7 @@ static Base *mesh_separate_tagged(
}));
BM_mesh_elem_toolflags_ensure(bm_new); /* needed for 'duplicate' bmo */
CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0);
CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0);
CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0);
CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0);
CustomData_bmesh_init_pool(&bm_new->vdata, bm_mesh_allocsize_default.totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm_new->edata, bm_mesh_allocsize_default.totedge, BM_EDGE);
CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
BM_mesh_copy_init_customdata(bm_new, bm_old, &bm_mesh_allocsize_default);
/* Take into account user preferences for duplicating actions. */
const eDupli_ID_Flags dupflag = USER_DUP_MESH | (U.dupflag & USER_DUP_ACT);

View File

@ -2231,10 +2231,13 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
link->tosock->new_sock);
}
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
Main *bmain = CTX_data_main(C);
ntreeUpdateTree(bmain, snode->edittree);
snode_notify(C, snode);
snode_dag_update(C, snode);
/* Pasting nodes can create arbitrary new relations, because nodes can reference IDs. */
DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
}

View File

@ -69,6 +69,12 @@ static void attribute_search_update_fn(
UI_search_item_add(items, str, (void *)str, ICON_ADD, 0, 0);
}
if (str[0] == '\0' && !is_first) {
/* Allow clearing the text field when the string is empty, but not on the first pass,
* or opening an attribute field for the first time would show this search item. */
UI_search_item_add(items, str, (void *)str, ICON_X, 0, 0);
}
/* Skip the filter when the menu is first opened, so all of the items are visible. */
if (is_first) {
for (const std::string &attribute_name : attribute_name_hints) {

View File

@ -38,11 +38,9 @@ struct bContext;
struct bNode;
struct bNodeLink;
struct bNodeSocket;
struct uiBut;
struct wmGizmoGroupType;
struct wmKeyConfig;
struct wmWindow;
struct uiBlock;
#ifdef __cplusplus
extern "C" {

View File

@ -550,7 +550,7 @@ static void applyObjectConstraintSize(TransInfo *t,
}
static void constraints_rotation_impl(TransInfo *t,
float axismtx[3][3],
const float axismtx[3][3],
float r_vec[3],
float *r_angle)
{
@ -621,7 +621,7 @@ static void applyObjectConstraintRot(
{
if (t->con.mode & CON_APPLY) {
float tmp_axismtx[3][3];
float(*axismtx)[3];
const float(*axismtx)[3];
/* on setup call, use first object */
if (td == NULL) {

View File

@ -606,7 +606,7 @@ void immUniform4fv(const char *name, const float data[4])
/* Note array index is not supported for name (i.e: "array[0]"). */
void immUniformArray4fv(const char *name, const float *data, int count)
{
GPU_shader_uniform_4fv_array(imm->shader, name, count, (float(*)[4])data);
GPU_shader_uniform_4fv_array(imm->shader, name, count, (const float(*)[4])data);
}
void immUniformMatrix4fv(const char *name, const float data[4][4])

View File

@ -32,7 +32,6 @@ extern "C" {
struct ImBuf;
struct OCIO_ConstCPUProcessorRcPtr;
struct OCIO_ConstProcessorRcPtr;
extern float imbuf_luma_coefficients[3];
extern float imbuf_xyz_to_rgb[3][3];

View File

@ -6062,7 +6062,9 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_relative_paths", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_RELPATHS);
RNA_def_property_ui_text(
prop, "Relative Paths", "Default relative path option for the file selector");
prop,
"Relative Paths",
"Default relative path option for the file selector, when no path is defined yet");
prop = RNA_def_property(srna, "use_file_compression", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_FILECOMPRESS);

View File

@ -187,16 +187,11 @@ BLI_NOINLINE void DerivedNodeTree::relink_group_inputs(const NodeTreeRef &group_
if (node_refs.size() == 0) {
return;
}
/* TODO: Pick correct group input node if there are more than one. */
const NodeRef &input_node_ref = *node_refs[0];
DNode &input_node = *nodes_by_id[input_node_ref.id()];
int input_amount = group_node.inputs().size();
BLI_assert(input_amount == input_node_ref.outputs().size() - 1);
for (int input_index : IndexRange(input_amount)) {
DInputSocket *outside_group = group_node.inputs_[input_index];
DOutputSocket *inside_group = input_node.outputs_[input_index];
for (DOutputSocket *outside_connected : outside_group->linked_sockets_) {
outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group);
@ -206,21 +201,27 @@ BLI_NOINLINE void DerivedNodeTree::relink_group_inputs(const NodeTreeRef &group_
outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group);
}
for (DInputSocket *inside_connected : inside_group->linked_sockets_) {
inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group);
for (const NodeRef *input_node_ref : node_refs) {
DNode &input_node = *nodes_by_id[input_node_ref->id()];
DOutputSocket *inside_group = input_node.outputs_[input_index];
for (DOutputSocket *outside_connected : outside_group->linked_sockets_) {
inside_connected->linked_sockets_.append(outside_connected);
outside_connected->linked_sockets_.append(inside_connected);
for (DInputSocket *inside_connected : inside_group->linked_sockets_) {
inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group);
for (DOutputSocket *outside_connected : outside_group->linked_sockets_) {
inside_connected->linked_sockets_.append(outside_connected);
outside_connected->linked_sockets_.append(inside_connected);
}
for (DGroupInput *outside_connected : outside_group->linked_group_inputs_) {
inside_connected->linked_group_inputs_.append(outside_connected);
outside_connected->linked_sockets_.append(inside_connected);
}
}
for (DGroupInput *outside_connected : outside_group->linked_group_inputs_) {
inside_connected->linked_group_inputs_.append(outside_connected);
outside_connected->linked_sockets_.append(inside_connected);
}
inside_group->linked_sockets_.clear();
}
inside_group->linked_sockets_.clear();
outside_group->linked_sockets_.clear();
outside_group->linked_group_inputs_.clear();
}

View File

@ -279,8 +279,8 @@ static void pygpu_batch__tp_dealloc(BPyGPUBatch *self)
GPU_batch_discard(self->batch);
#ifdef USE_GPU_PY_REFERENCES
PyObject_GC_UnTrack(self);
if (self->references) {
PyObject_GC_UnTrack(self);
pygpu_batch__tp_clear(self);
Py_XDECREF(self->references);
}

View File

@ -202,8 +202,7 @@ static void pygpu_buffer__tp_dealloc(BPyGPUBuffer *self)
{
if (self->parent) {
PyObject_GC_UnTrack(self);
pygpu_buffer__tp_clear(self);
Py_XDECREF(self->parent);
Py_CLEAR(self->parent);
}
else {
MEM_freeN(self->buf.as_void);

View File

@ -336,8 +336,8 @@ static PyObject *pygpu_offscreen_draw_view3d(BPyGPUOffScreen *self, PyObject *ar
region,
GPU_offscreen_width(self->ofs),
GPU_offscreen_height(self->ofs),
(float(*)[4])py_mat_view->matrix,
(float(*)[4])py_mat_projection->matrix,
(const float(*)[4])py_mat_view->matrix,
(const float(*)[4])py_mat_projection->matrix,
true,
true,
"",

View File

@ -216,7 +216,7 @@ static PyObject *make_app_info(void)
#undef SetObjItem
if (PyErr_Occurred()) {
Py_CLEAR(app_info);
Py_DECREF(app_info);
return NULL;
}
return app_info;

View File

@ -79,8 +79,8 @@ static PyObject *make_alembic_info(void)
SetStrItem("Unknown");
#endif
if (PyErr_Occurred()) {
Py_CLEAR(alembic_info);
if (UNLIKELY(PyErr_Occurred())) {
Py_DECREF(alembic_info);
return NULL;
}

View File

@ -116,8 +116,8 @@ static PyObject *make_ffmpeg_info(void)
#undef FFMPEG_LIB_VERSION
if (PyErr_Occurred()) {
Py_CLEAR(ffmpeg_info);
if (UNLIKELY(PyErr_Occurred())) {
Py_DECREF(ffmpeg_info);
return NULL;
}

View File

@ -81,8 +81,8 @@ static PyObject *make_ocio_info(void)
SetStrItem("Unknown");
#endif
if (PyErr_Occurred()) {
Py_CLEAR(ocio_info);
if (UNLIKELY(PyErr_Occurred())) {
Py_DECREF(ocio_info);
return NULL;
}

View File

@ -77,8 +77,8 @@ static PyObject *make_oiio_info(void)
SetStrItem("Unknown");
#endif
if (PyErr_Occurred()) {
Py_CLEAR(oiio_info);
if (UNLIKELY(PyErr_Occurred())) {
Py_DECREF(oiio_info);
return NULL;
}

View File

@ -74,8 +74,8 @@ static PyObject *make_opensubdiv_info(void)
SetStrItem("Unknown");
#endif
if (PyErr_Occurred()) {
Py_CLEAR(opensubdiv_info);
if (UNLIKELY(PyErr_Occurred())) {
Py_DECREF(opensubdiv_info);
return NULL;
}

View File

@ -81,8 +81,8 @@ static PyObject *make_openvdb_info(void)
SetStrItem("Unknown");
#endif
if (PyErr_Occurred()) {
Py_CLEAR(openvdb_info);
if (UNLIKELY(PyErr_Occurred())) {
Py_DECREF(openvdb_info);
return NULL;
}

View File

@ -114,8 +114,8 @@ static PyObject *make_sdl_info(void)
SetObjItem(PyBool_FromLong(0));
#endif
if (PyErr_Occurred()) {
Py_CLEAR(sdl_info);
if (UNLIKELY(PyErr_Occurred())) {
Py_DECREF(sdl_info);
return NULL;
}

View File

@ -80,8 +80,8 @@ static PyObject *make_usd_info(void)
SetStrItem("Unknown");
#endif
if (PyErr_Occurred()) {
Py_CLEAR(usd_info);
if (UNLIKELY(PyErr_Occurred())) {
Py_DECREF(usd_info);
return NULL;
}

View File

@ -34,7 +34,6 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@ -68,9 +67,11 @@ typedef struct {
BlendHandle *blo_handle;
int flag;
PyObject *dict;
/* Borrowed reference to the `bmain`, taken from the RNA instance of #RNA_BlendDataLibraries. */
Main *bmain;
} BPy_Library;
static PyObject *bpy_lib_load(PyObject *self, PyObject *args, PyObject *kwds);
static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *kwds);
static PyObject *bpy_lib_enter(BPy_Library *self);
static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *args);
static PyObject *bpy_lib_dir(BPy_Library *self);
@ -182,9 +183,9 @@ PyDoc_STRVAR(
" :type relative: bool\n"
" :arg assets_only: If True, only list data-blocks marked as assets.\n"
" :type assets_only: bool\n");
static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *kw)
{
Main *bmain = CTX_data_main(BPY_context_get());
Main *bmain = self->ptr.data; /* Typically #G_MAIN */
BPy_Library *ret;
const char *filename = NULL;
bool is_rel = false, is_link = false, use_assets_only = false;
@ -210,6 +211,8 @@ static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *
BLI_strncpy(ret->abspath, filename, sizeof(ret->abspath));
BLI_path_abs(ret->abspath, BKE_main_blendfile_path(bmain));
ret->bmain = bmain;
ret->blo_handle = NULL;
ret->flag = ((is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0) |
(use_assets_only ? FILE_ASSETS_ONLY : 0));
@ -333,7 +336,7 @@ static void bpy_lib_exit_warn_type(BPy_Library *self, PyObject *item)
static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
{
Main *bmain = CTX_data_main(BPY_context_get());
Main *bmain = self->bmain;
Main *mainl = NULL;
const int err = 0;
const bool do_append = ((self->flag & FILE_LINK) == 0);
@ -477,7 +480,7 @@ static PyObject *bpy_lib_dir(BPy_Library *self)
PyMethodDef BPY_library_load_method_def = {
"load",
(PyCFunction)bpy_lib_load,
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
METH_VARARGS | METH_KEYWORDS,
bpy_lib_load_doc,
};

View File

@ -71,7 +71,7 @@ PyDoc_STRVAR(
" :type fake_user: bool\n"
" :arg compress: When True, write a compressed blend file.\n"
" :type compress: bool\n");
static PyObject *bpy_lib_write(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
static PyObject *bpy_lib_write(BPy_PropertyRNA *self, PyObject *args, PyObject *kw)
{
/* args */
const char *filepath;
@ -114,7 +114,7 @@ static PyObject *bpy_lib_write(PyObject *UNUSED(self), PyObject *args, PyObject
return NULL;
}
Main *bmain_src = G_MAIN;
Main *bmain_src = self->ptr.data; /* Typically #G_MAIN */
int write_flags = 0;
if (use_compress) {
@ -220,6 +220,6 @@ finally:
PyMethodDef BPY_library_write_method_def = {
"write",
(PyCFunction)bpy_lib_write,
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
METH_VARARGS | METH_KEYWORDS,
bpy_lib_write_doc,
};

View File

@ -203,10 +203,8 @@ static const EnumPropertyItem property_subtype_array_items[] = {
static void bpy_prop_deferred_dealloc(BPy_PropDeferred *self)
{
if (self->kw) {
PyObject_GC_UnTrack(self);
Py_CLEAR(self->kw);
}
PyObject_GC_UnTrack(self);
Py_CLEAR(self->kw);
PyObject_GC_Del(self);
}

View File

@ -1204,15 +1204,15 @@ static void pyrna_struct_dealloc(BPy_StructRNA *self)
static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
{
if (self->reference) {
// PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */
pyrna_struct_clear(self);
PyObject_GC_UnTrack(self);
Py_CLEAR(self->reference);
}
/* Reference is now NULL. */
if (reference) {
self->reference = reference;
Py_INCREF(reference);
// PyObject_GC_Track(self); /* INITIALIZED TRACKED ? */
PyObject_GC_Track(self);
}
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
@ -4622,6 +4622,19 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject
if (ret == NULL) {
PyErr_Restore(error_type, error_value, error_traceback);
}
else {
if (Py_TYPE(ret) == &PyMethodDescr_Type) {
PyMethodDef *m = ((PyMethodDescrObject *)ret)->d_method;
/* TODO: #METH_CLASS */
if (m->ml_flags & METH_STATIC) {
/* Keep 'ret' as-is. */
}
else {
Py_DECREF(ret);
ret = PyCMethod_New(m, (PyObject *)self, NULL, NULL);
}
}
}
}
}
@ -5822,6 +5835,11 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *
BPy_StructRNA *ret;
if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) {
ret->ptr = base->ptr;
#ifdef USE_PYRNA_STRUCT_REFERENCE
/* #PyType_GenericAlloc will have set tracking.
* We only want tracking when `StructRNA.reference` has been set. */
PyObject_GC_UnTrack(ret);
#endif
}
/* Pass on exception & NULL if tp_alloc fails. */
return (PyObject *)ret;
@ -6525,7 +6543,11 @@ PyTypeObject pyrna_struct_Type = {
NULL, /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* long tp_flags; */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
#ifdef USE_PYRNA_STRUCT_REFERENCE
| Py_TPFLAGS_HAVE_GC
#endif
, /* long tp_flags; */
NULL, /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
@ -7462,13 +7484,28 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
if (tp) {
pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0);
#ifdef USE_PYRNA_STRUCT_REFERENCE
/* #PyType_GenericAlloc will have set tracking.
* We only want tracking when `StructRNA.reference` has been set. */
if (pyrna != NULL) {
PyObject_GC_UnTrack(pyrna);
}
#endif
Py_DECREF(tp); /* srna owns, can't hold a reference. */
}
else {
CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type));
#ifdef USE_PYRNA_STRUCT_REFERENCE
pyrna = (BPy_StructRNA *)PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type);
#else
pyrna = (BPy_StructRNA *)PyObject_New(BPy_StructRNA, &pyrna_struct_Type);
#endif
#ifdef USE_WEAKREFS
pyrna->in_weakreflist = NULL;
if (pyrna != NULL) {
pyrna->in_weakreflist = NULL;
}
#endif
}
}

View File

@ -30,7 +30,6 @@ extern "C" {
struct ListBase;
struct Scene;
struct Sequence;
struct bContext;
/* SeqLoadData.flags */
typedef enum eSeqLoadFlags {

View File

@ -1776,7 +1776,12 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
filepath,
fileflags,
&(const struct BlendFileWriteParams){
.remap_mode = BLO_WRITE_PATH_REMAP_RELATIVE,
/* Make all paths absolute when saving the startup file.
* On load the `G.relbase_valid` will be false so the paths
* wont have a base for resolving the relative paths. */
.remap_mode = BLO_WRITE_PATH_REMAP_ABSOLUTE,
/* Don't apply any path changes to the current blend file. */
.use_save_as_copy = true,
},
op->reports) == 0) {
printf("fail\n");

View File

@ -291,7 +291,7 @@ void WM_operator_properties_select_random(wmOperatorType *ot)
1.0f,
"Ratio",
"Portion of items to select randomly",
0.f,
0.0f,
1.0f);
RNA_def_int(ot->srna,
"seed",

View File

@ -610,6 +610,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
printf("\n");
printf("Misc Options:\n");
BLI_args_print_arg_doc(ba, "--open-last");
BLI_args_print_arg_doc(ba, "--app-template");
BLI_args_print_arg_doc(ba, "--factory-startup");
BLI_args_print_arg_doc(ba, "--enable-event-simulate");
@ -2008,7 +2009,7 @@ static int arg_handle_load_last_file(int UNUSED(argc), const char **UNUSED(argv)
const RecentFile *recent_file = G.recent_files.first;
const char *fake_argv[] = {recent_file->filepath};
return arg_handle_load_file(1, fake_argv, data);
return arg_handle_load_file(ARRAY_SIZE(fake_argv), fake_argv, data);
}
void main_args_setup(bContext *C, bArgs *ba)

View File

@ -82,6 +82,7 @@ elseif(APPLE)
# are used as dependencies of other test libraries.
foreach(_lib ${_test_libs})
list(REMOVE_ITEM _test_libs_dependencies ${_lib})
add_dependencies(blender_test ${_lib})
target_link_options(blender_test PRIVATE "LINKER:-force_load,$<TARGET_FILE:${_lib}>")
endforeach()

View File

@ -15,7 +15,8 @@ class TestBlendFileSaveLoadBasic(TestHelper):
self.args = args
def test_save_load(self):
bpy.ops.wm.read_factory_settings()
bpy.ops.wm.read_homefile(use_empty=True, use_factory_startup=True)
bpy.data.meshes.new("OrphanedMesh")
output_dir = self.args.output_dir
@ -71,6 +72,9 @@ def argparse_create():
def main():
args = argparse_create().parse_args()
# Don't write thumbnails into the home directory.
bpy.context.preferences.filepaths.use_save_preview_images = False
for Test in TESTS:
Test(args).run_all_tests()

View File

@ -15,7 +15,9 @@ class TestBlendLibLinkSaveLoadBasic(TestHelper):
self.args = args
def test_link_save_load(self):
bpy.ops.wm.read_factory_settings()
bpy.ops.wm.read_homefile(use_empty=True, use_factory_startup=True)
me = bpy.data.meshes.new("LibMesh")
me.use_fake_user = True
@ -26,7 +28,7 @@ class TestBlendLibLinkSaveLoadBasic(TestHelper):
bpy.ops.wm.save_as_mainfile(filepath=output_path, check_existing=False, compress=False)
bpy.ops.wm.read_factory_settings()
bpy.ops.wm.read_homefile(use_empty=True, use_factory_startup=True)
bpy.data.orphans_purge()
link_dir = os.path.join(output_path, "Mesh")
@ -68,6 +70,9 @@ def argparse_create():
def main():
args = argparse_create().parse_args()
# Don't write thumbnails into the home directory.
bpy.context.preferences.filepaths.use_save_preview_images = False
for Test in TESTS:
Test(args).run_all_tests()