Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_compiler_compat.h34
-rw-r--r--source/blender/blenlib/BLI_fileops.h1
-rw-r--r--source/blender/blenlib/BLI_gsqueue.h2
-rw-r--r--source/blender/blenlib/BLI_math_geom.h6
-rw-r--r--source/blender/blenlib/intern/BLI_temporary_allocator.cc2
-rw-r--r--source/blender/blenlib/intern/BLI_timer.c1
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.c126
-rw-r--r--source/blender/blenlib/intern/expr_pylike_eval.c8
-rw-r--r--source/blender/blenlib/intern/fileops.c193
-rw-r--r--source/blender/blenlib/intern/scanfill.c2
-rw-r--r--source/blender/blenlib/intern/storage.c1
11 files changed, 329 insertions, 47 deletions
diff --git a/source/blender/blenlib/BLI_compiler_compat.h b/source/blender/blenlib/BLI_compiler_compat.h
index bd1cd327d3c..312991e7f15 100644
--- a/source/blender/blenlib/BLI_compiler_compat.h
+++ b/source/blender/blenlib/BLI_compiler_compat.h
@@ -15,7 +15,7 @@
*/
#ifndef __BLI_COMPILER_COMPAT_H__
-# define __BLI_COMPILER_COMPAT_H__
+#define __BLI_COMPILER_COMPAT_H__
/** \file
* \ingroup bli
@@ -23,32 +23,32 @@
* Use to help with cross platform portability.
*/
-# if defined(_MSC_VER)
-# define alloca _alloca
-# endif
+#if defined(_MSC_VER)
+# define alloca _alloca
+#endif
-# if (defined(__GNUC__) || defined(__clang__)) && defined(__cplusplus)
+#if (defined(__GNUC__) || defined(__clang__)) && defined(__cplusplus)
extern "C++" {
/* Some magic to be sure we don't have reference in the type. */
template<typename T> static inline T decltype_helper(T x)
{
return x;
}
-# define typeof(x) decltype(decltype_helper(x))
+# define typeof(x) decltype(decltype_helper(x))
}
-# endif
+#endif
/* little macro so inline keyword works */
-# if defined(_MSC_VER)
-# define BLI_INLINE static __forceinline
-# else
-# define BLI_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__))
-# endif
+#if defined(_MSC_VER)
+# define BLI_INLINE static __forceinline
+#else
+# define BLI_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__))
+#endif
-# if defined(__GNUC__)
-# define BLI_NOINLINE __attribute__((noinline))
-# else
-# define BLI_NOINLINE
-# endif
+#if defined(__GNUC__)
+# define BLI_NOINLINE __attribute__((noinline))
+#else
+# define BLI_NOINLINE
+#endif
#endif /* __BLI_COMPILER_COMPAT_H__ */
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index d78f167a8fd..bdf7588291f 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -50,6 +50,7 @@ int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
int BLI_copy(const char *path, const char *to) ATTR_NONNULL();
int BLI_rename(const char *from, const char *to) ATTR_NONNULL();
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL();
+int BLI_delete_soft(const char *path, const char **error_message) ATTR_NONNULL();
#if 0 /* Unused */
int BLI_move(const char *path, const char *to) ATTR_NONNULL();
int BLI_create_symlink(const char *path, const char *to) ATTR_NONNULL();
diff --git a/source/blender/blenlib/BLI_gsqueue.h b/source/blender/blenlib/BLI_gsqueue.h
index 4bd53dfddbe..b8a87e9d9fa 100644
--- a/source/blender/blenlib/BLI_gsqueue.h
+++ b/source/blender/blenlib/BLI_gsqueue.h
@@ -26,7 +26,7 @@
typedef struct _GSQueue GSQueue;
-GSQueue *BLI_gsqueue_new(size_t elem_size);
+GSQueue *BLI_gsqueue_new(const size_t elem_size);
bool BLI_gsqueue_is_empty(const GSQueue *gq);
size_t BLI_gsqueue_len(const GSQueue *gq);
void BLI_gsqueue_pop(GSQueue *gq, void *r_item);
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 87517ebe060..eec5d214473 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -97,10 +97,10 @@ bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3],
bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
-bool is_quad_flip_v3_first_third_fast(const float v0[3],
- const float v1[3],
+bool is_quad_flip_v3_first_third_fast(const float v1[3],
const float v2[3],
- const float v3[3]);
+ const float v3[3],
+ const float v4[3]);
/********************************* Distance **********************************/
diff --git a/source/blender/blenlib/intern/BLI_temporary_allocator.cc b/source/blender/blenlib/intern/BLI_temporary_allocator.cc
index e41cf36f66d..b145e65530d 100644
--- a/source/blender/blenlib/intern/BLI_temporary_allocator.cc
+++ b/source/blender/blenlib/intern/BLI_temporary_allocator.cc
@@ -73,7 +73,7 @@ struct ThreadLocalBuffers {
}
};
-thread_local ThreadLocalBuffers local_storage;
+static thread_local ThreadLocalBuffers local_storage;
void *BLI_temporary_allocate(uint size)
{
diff --git a/source/blender/blenlib/intern/BLI_timer.c b/source/blender/blenlib/intern/BLI_timer.c
index 0443dea9a2e..af987587d90 100644
--- a/source/blender/blenlib/intern/BLI_timer.c
+++ b/source/blender/blenlib/intern/BLI_timer.c
@@ -42,7 +42,6 @@ typedef struct TimedFunction {
typedef struct TimerContainer {
ListBase funcs;
- bool file_load_cb_registered;
} TimerContainer;
static TimerContainer GlobalTimer = {{0}};
diff --git a/source/blender/blenlib/intern/delaunay_2d.c b/source/blender/blenlib/intern/delaunay_2d.c
index d5dcd40346f..af4fa9fa54e 100644
--- a/source/blender/blenlib/intern/delaunay_2d.c
+++ b/source/blender/blenlib/intern/delaunay_2d.c
@@ -325,6 +325,18 @@ static bool exists_edge(const CDTVert *a, const CDTVert *b)
return false;
}
+/** Is the vertex v incident on face f? */
+static bool vert_touches_face(const CDTVert *v, const CDTFace *f)
+{
+ SymEdge *se = v->symedge;
+ do {
+ if (se->face == f) {
+ return true;
+ }
+ } while ((se = se->rot) != v->symedge);
+ return false;
+}
+
/**
* Assume s1 and s2 are both SymEdges in a face with > 3 sides,
* and one is not the next of the other.
@@ -1901,35 +1913,108 @@ static void dissolve_symedge(CDT_state *cdt, SymEdge *se)
delete_edge(cdt, se);
}
-static void remove_non_constraint_edges(CDT_state *cdt, const bool valid_bmesh)
+/* Remove all non-constraint edges. */
+static void remove_non_constraint_edges(CDT_state *cdt)
+{
+ LinkNode *ln;
+ CDTEdge *e;
+ SymEdge *se;
+
+ for (ln = cdt->edges; ln; ln = ln->next) {
+ e = (CDTEdge *)ln->link;
+ se = &e->symedges[0];
+ if (!is_deleted_edge(e) && !is_constrained_edge(e)) {
+ dissolve_symedge(cdt, se);
+ }
+ }
+}
+
+/*
+ * Remove the non-constraint edges, but leave enough of them so that all of the
+ * faces that would be bmesh faces (that is, the faces that have some input representative)
+ * are valid: they can't have holes, they can't have repeated vertices, and they can't have
+ * repeated edges.
+ *
+ * Not essential, but to make the result look more aesthetically nice,
+ * remove the edges in order of decreasing length, so that it is more likely that the
+ * final remaining support edges are short, and therefore likely to make a fairly
+ * direct path from an outer face to an inner hole face.
+ */
+
+/* For sorting edges by decreasing length (squared). */
+struct EdgeToSort {
+ double len_squared;
+ CDTEdge *e;
+};
+
+static int edge_to_sort_cmp(const void *a, const void *b)
+{
+ const struct EdgeToSort *e1 = a;
+ const struct EdgeToSort *e2 = b;
+
+ if (e1->len_squared > e2->len_squared) {
+ return -1;
+ }
+ else if (e1->len_squared < e2->len_squared) {
+ return 1;
+ }
+ return 0;
+}
+
+static void remove_non_constraint_edges_leave_valid_bmesh(CDT_state *cdt)
{
LinkNode *ln;
CDTEdge *e;
SymEdge *se, *se2;
CDTFace *fleft, *fright;
bool dissolve;
+ size_t nedges;
+ int i, ndissolvable;
+ const double *co1, *co2;
+ struct EdgeToSort *sorted_edges;
+ nedges = 0;
+ for (ln = cdt->edges; ln; ln = ln->next) {
+ nedges++;
+ }
+ if (nedges == 0) {
+ return;
+ }
+ sorted_edges = BLI_memarena_alloc(cdt->arena, nedges * sizeof(*sorted_edges));
+ i = 0;
for (ln = cdt->edges; ln; ln = ln->next) {
e = (CDTEdge *)ln->link;
- dissolve = !is_deleted_edge(e) && !is_constrained_edge(e);
- if (dissolve) {
- se = &e->symedges[0];
- if (valid_bmesh && !edge_touches_frame(e)) {
- fleft = se->face;
- fright = sym(se)->face;
- if (fleft != cdt->outer_face && fright != cdt->outer_face &&
- (fleft->input_ids != NULL || fright->input_ids != NULL)) {
- /* Is there another symedge with same left and right faces? */
- for (se2 = se->next; dissolve && se2 != se; se2 = se2->next) {
- if (sym(se2)->face == fright) {
- dissolve = false;
- }
+ if (!is_deleted_edge(e) && !is_constrained_edge(e)) {
+ sorted_edges[i].e = e;
+ co1 = e->symedges[0].vert->co;
+ co2 = e->symedges[1].vert->co;
+ sorted_edges[i].len_squared = len_squared_v2v2_db(co1, co2);
+ i++;
+ }
+ }
+ ndissolvable = i;
+ qsort(sorted_edges, ndissolvable, sizeof(*sorted_edges), edge_to_sort_cmp);
+ for (i = 0; i < ndissolvable; i++) {
+ e = sorted_edges[i].e;
+ se = &e->symedges[0];
+ dissolve = true;
+ if (!edge_touches_frame(e)) {
+ fleft = se->face;
+ fright = sym(se)->face;
+ if (fleft != cdt->outer_face && fright != cdt->outer_face &&
+ (fleft->input_ids != NULL || fright->input_ids != NULL)) {
+ /* Is there another symedge with same left and right faces?
+ * Or is there a vertex not part of e touching the same left and right faces? */
+ for (se2 = se->next; dissolve && se2 != se; se2 = se2->next) {
+ if (sym(se2)->face == fright ||
+ (se2->vert != se->next->vert && vert_touches_face(se2->vert, fright))) {
+ dissolve = false;
}
}
}
- if (dissolve) {
- dissolve_symedge(cdt, se);
- }
+ }
+ if (dissolve) {
+ dissolve_symedge(cdt, se);
}
}
}
@@ -2066,8 +2151,11 @@ static void prepare_cdt_for_output(CDT_state *cdt, const CDT_output_type output_
UNUSED_VARS(f);
#endif
- if (output_type == CDT_CONSTRAINTS || output_type == CDT_CONSTRAINTS_VALID_BMESH) {
- remove_non_constraint_edges(cdt, output_type == CDT_CONSTRAINTS_VALID_BMESH);
+ if (output_type == CDT_CONSTRAINTS) {
+ remove_non_constraint_edges(cdt);
+ }
+ else if (output_type == CDT_CONSTRAINTS_VALID_BMESH) {
+ remove_non_constraint_edges_leave_valid_bmesh(cdt);
}
else if (output_type == CDT_FULL || output_type == CDT_INSIDE) {
remove_outer_edges(cdt, output_type == CDT_INSIDE);
diff --git a/source/blender/blenlib/intern/expr_pylike_eval.c b/source/blender/blenlib/intern/expr_pylike_eval.c
index 14fc4c5bf26..c7631f8991e 100644
--- a/source/blender/blenlib/intern/expr_pylike_eval.c
+++ b/source/blender/blenlib/intern/expr_pylike_eval.c
@@ -504,7 +504,9 @@ static bool parse_add_func(ExprParseState *state, eOpCode code, int args, void *
if (jmp_gap >= 1 && prev_ops[-1].opcode == OPCODE_CONST) {
UnaryOpFunc func = funcptr;
- double result = func(prev_ops[-1].arg.dval);
+ /* volatile because some compilers overly aggressive optimize this call out.
+ * see D6012 for details. */
+ volatile double result = func(prev_ops[-1].arg.dval);
if (fetestexcept(FE_DIVBYZERO | FE_INVALID) == 0) {
prev_ops[-1].arg.dval = result;
@@ -520,7 +522,9 @@ static bool parse_add_func(ExprParseState *state, eOpCode code, int args, void *
prev_ops[-1].opcode == OPCODE_CONST) {
BinaryOpFunc func = funcptr;
- double result = func(prev_ops[-2].arg.dval, prev_ops[-1].arg.dval);
+ /* volatile because some compilers overly aggressive optimize this call out.
+ * see D6012 for details. */
+ volatile double result = func(prev_ops[-2].arg.dval, prev_ops[-1].arg.dval);
if (fetestexcept(FE_DIVBYZERO | FE_INVALID) == 0) {
prev_ops[-2].arg.dval = result;
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 99149f5ea42..3a45989fb63 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -33,16 +33,24 @@
#include "zlib.h"
#ifdef WIN32
+# include <windows.h>
+# include <shellapi.h>
+# include <shobjidl.h>
# include <io.h>
# include "BLI_winstuff.h"
# include "BLI_fileops_types.h"
# include "utf_winfunc.h"
# include "utfconv.h"
#else
+# if defined(__APPLE__)
+# include <CoreFoundation/CoreFoundation.h>
+# include <objc/runtime.h>
+# include <objc/message.h>
+# endif
# include <sys/param.h>
# include <dirent.h>
# include <unistd.h>
-# include <sys/stat.h>
+# include <sys/wait.h>
#endif
#include "MEM_guardedalloc.h"
@@ -288,6 +296,64 @@ int BLI_access(const char *filename, int mode)
return uaccess(filename, mode);
}
+static bool delete_soft(const wchar_t *path_16, const char **error_message)
+{
+ /* Deletes file or directory to recycling bin. The latter moves all contained files and
+ * directories recursively to the recycling bin as well. */
+ IFileOperation *pfo;
+ IShellItem *pSI;
+
+ HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+
+ if (FAILED(hr)) {
+ *error_message = "Failed to initialize COM";
+ goto error_1;
+ }
+
+ hr = CoCreateInstance(
+ &CLSID_FileOperation, NULL, CLSCTX_ALL, &IID_IFileOperation, (void **)&pfo);
+ if (FAILED(hr)) {
+ *error_message = "Failed to create FileOperation instance";
+ goto error_2;
+ }
+
+ /* Flags for deletion:
+ * FOF_ALLOWUNDO: Enables moving file to recycling bin.
+ * FOF_SILENT: Don't show progress dialog box.
+ * FOF_WANTNUKEWARNING: Show dialog box if file can't be moved to recycling bin. */
+ hr = pfo->lpVtbl->SetOperationFlags(pfo, FOF_ALLOWUNDO | FOF_SILENT | FOF_WANTNUKEWARNING);
+
+ if (FAILED(hr)) {
+ *error_message = "Failed to set operation flags";
+ goto error_2;
+ }
+
+ hr = SHCreateItemFromParsingName(path_16, NULL, &IID_IShellItem, (void **)&pSI);
+ if (FAILED(hr)) {
+ *error_message = "Failed to parse path";
+ goto error_2;
+ }
+
+ hr = pfo->lpVtbl->DeleteItem(pfo, pSI, NULL);
+ if (FAILED(hr)) {
+ *error_message = "Failed to prepare delete operation";
+ goto error_2;
+ }
+
+ hr = pfo->lpVtbl->PerformOperations(pfo);
+
+ if (FAILED(hr)) {
+ *error_message = "Failed to delete file or directory";
+ }
+
+error_2:
+ pfo->lpVtbl->Release(pfo);
+ CoUninitialize(); /* Has to be uninitialized when CoInitializeEx returns either S_OK or S_FALSE
+ */
+error_1:
+ return FAILED(hr);
+}
+
static bool delete_unique(const char *path, const bool dir)
{
bool err;
@@ -370,6 +436,24 @@ int BLI_delete(const char *file, bool dir, bool recursive)
return err;
}
+/**
+ * Moves the files or directories to the recycling bin.
+ */
+int BLI_delete_soft(const char *file, const char **error_message)
+{
+ int err;
+
+ BLI_assert(!BLI_path_is_rel(file));
+
+ UTF16_ENCODE(file);
+
+ err = delete_soft(file_16, error_message);
+
+ UTF16_UN_ENCODE(file);
+
+ return err;
+}
+
/* Not used anywhere! */
# if 0
int BLI_move(const char *file, const char *to)
@@ -720,6 +804,100 @@ static int delete_single_file(const char *from, const char *UNUSED(to))
return RecursiveOp_Callback_OK;
}
+# ifdef __APPLE__
+static int delete_soft(const char *file, const char **error_message)
+{
+ int ret = -1;
+
+ Class NSAutoreleasePoolClass = objc_getClass("NSAutoreleasePool");
+ SEL allocSel = sel_registerName("alloc");
+ SEL initSel = sel_registerName("init");
+ id poolAlloc = ((id(*)(Class, SEL))objc_msgSend)(NSAutoreleasePoolClass, allocSel);
+ id pool = ((id(*)(id, SEL))objc_msgSend)(poolAlloc, initSel);
+
+ Class NSStringClass = objc_getClass("NSString");
+ SEL stringWithUTF8StringSel = sel_registerName("stringWithUTF8String:");
+ id pathString = ((id(*)(Class, SEL, const char *))objc_msgSend)(
+ NSStringClass, stringWithUTF8StringSel, file);
+
+ Class NSFileManagerClass = objc_getClass("NSFileManager");
+ SEL defaultManagerSel = sel_registerName("defaultManager");
+ id fileManager = ((id(*)(Class, SEL))objc_msgSend)(NSFileManagerClass, defaultManagerSel);
+
+ Class NSURLClass = objc_getClass("NSURL");
+ SEL fileURLWithPathSel = sel_registerName("fileURLWithPath:");
+ id nsurl = ((id(*)(Class, SEL, id))objc_msgSend)(NSURLClass, fileURLWithPathSel, pathString);
+
+ SEL trashItemAtURLSel = sel_registerName("trashItemAtURL:resultingItemURL:error:");
+ BOOL deleteSuccessful = ((BOOL(*)(id, SEL, id, id, id))objc_msgSend)(
+ fileManager, trashItemAtURLSel, nsurl, nil, nil);
+
+ if (deleteSuccessful) {
+ ret = 0;
+ }
+ else {
+ *error_message = "The Cocoa API call to delete file or directory failed";
+ }
+
+ SEL drainSel = sel_registerName("drain");
+ ((void (*)(id, SEL))objc_msgSend)(pool, drainSel);
+
+ return ret;
+}
+# else
+static int delete_soft(const char *file, const char **error_message)
+{
+ const char *args[5];
+ const char *process_failed;
+
+ char *xdg_current_desktop = getenv("XDG_CURRENT_DESKTOP");
+ char *xdg_session_desktop = getenv("XDG_SESSION_DESKTOP");
+
+ if ((xdg_current_desktop != NULL && strcmp(xdg_current_desktop, "KDE") == 0) ||
+ (xdg_session_desktop != NULL && strcmp(xdg_session_desktop, "KDE") == 0)) {
+ args[0] = "kioclient5";
+ args[1] = "move";
+ args[2] = file;
+ args[3] = "trash:/";
+ args[4] = NULL;
+ process_failed = "kioclient5 reported failure";
+ }
+ else {
+ args[0] = "gio";
+ args[1] = "trash";
+ args[2] = file;
+ args[3] = NULL;
+ process_failed = "gio reported failure";
+ }
+
+ int pid = fork();
+
+ if (pid != 0) {
+ /* Parent process */
+ int wstatus = 0;
+
+ waitpid(pid, &wstatus, 0);
+
+ if (!WIFEXITED(wstatus)) {
+ *error_message =
+ "Blender may not support moving files or directories to trash on your system.";
+ return -1;
+ }
+ else if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus)) {
+ *error_message = process_failed;
+ return -1;
+ }
+
+ return 0;
+ }
+
+ execvp(args[0], (char **)args);
+
+ *error_message = "Forking process failed.";
+ return -1; /* This should only be reached if execvp fails and stack isn't replaced. */
+}
+# endif
+
FILE *BLI_fopen(const char *filename, const char *mode)
{
BLI_assert(!BLI_path_is_rel(filename));
@@ -770,6 +948,19 @@ int BLI_delete(const char *file, bool dir, bool recursive)
}
/**
+ * Soft deletes the specified file or directory (depending on dir) by moving the files to the
+ * recycling bin, optionally doing recursive delete of directory contents.
+ *
+ * \return zero on success (matching 'remove' behavior).
+ */
+int BLI_delete_soft(const char *file, const char **error_message)
+{
+ BLI_assert(!BLI_path_is_rel(file));
+
+ return delete_soft(file, error_message);
+}
+
+/**
* Do the two paths denote the same file-system object?
*/
static bool check_the_same(const char *path_a, const char *path_b)
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 08c3653153e..c9b0eb3ed5e 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -907,7 +907,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
return 0;
}
- axis_dominant_v3_to_m3(mat_2d, n);
+ axis_dominant_v3_to_m3_negate(mat_2d, n);
}
/* STEP 1: COUNT POLYS */
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 05a2d766fe0..fd5de717a24 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -209,7 +209,6 @@ int BLI_exists(const char *name)
BLI_stat_t st;
wchar_t *tmp_16 = alloc_utf16_from_8(name, 1);
int len, res;
- unsigned int old_error_mode;
len = wcslen(tmp_16);
/* in Windows #stat doesn't recognize dir ending on a slash