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:
authorThomas Dinges <blender@dingto.org>2013-06-20 00:40:54 +0400
committerThomas Dinges <blender@dingto.org>2013-06-20 00:40:54 +0400
commite6fc17415223d97a5a8c8bca0af443fb3a655699 (patch)
tree8696c810b22464262db029f55e937782cd64cc7b /source/blender
parentac4058a2117a24901f2462ba34d49e6714532148 (diff)
parent93af050824170913d716e42e918ab58c224ed7f1 (diff)
Merged revision(s) 57499-57586 from trunk/blender into soc-2013-dingto
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_autoexec.h31
-rw-r--r--source/blender/blenkernel/BKE_modifier.h25
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c65
-rw-r--r--source/blender/blenkernel/intern/autoexec.c70
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/displist.c23
-rw-r--r--source/blender/blenkernel/intern/editmesh_bvh.c8
-rw-r--r--source/blender/blenkernel/intern/mball.c649
-rw-r--r--source/blender/blenkernel/intern/modifier.c65
-rw-r--r--source/blender/blenlib/BLI_path_util.h2
-rw-r--r--source/blender/blenlib/BLI_utildefines.h16
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c3
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/writefile.c5
-rw-r--r--source/blender/bmesh/bmesh_class.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_path.c9
-rw-r--r--source/blender/editors/include/ED_mesh.h2
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/interface/interface.c20
-rw-r--r--source/blender/editors/interface/interface_handlers.c47
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c2
-rw-r--r--source/blender/editors/interface/interface_regions.c6
-rw-r--r--source/blender/editors/interface/interface_widgets.c30
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c83
-rw-r--r--source/blender/editors/object/object_vgroup.c4
-rw-r--r--source/blender/editors/screen/screendump.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c6
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c189
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h4
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c31
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c19
-rw-r--r--source/blender/editors/space_clip/space_clip.c2
-rw-r--r--source/blender/editors/space_file/file_intern.h4
-rw-r--r--source/blender/editors/space_file/filesel.c26
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_nla/nla_edit.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c86
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c67
-rw-r--r--source/blender/editors/transform/transform_conversions.c198
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c4
-rw-r--r--source/blender/freestyle/intern/application/AppCanvas.cpp4
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h14
-rw-r--r--source/blender/makesrna/intern/rna_space.c109
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c76
-rw-r--r--source/blender/makesrna/intern/rna_wm.c6
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c22
-rw-r--r--source/blender/windowmanager/WM_api.h3
-rw-r--r--source/blender/windowmanager/WM_types.h2
-rw-r--r--source/blender/windowmanager/intern/wm_files.c16
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c135
57 files changed, 1345 insertions, 876 deletions
diff --git a/source/blender/blenkernel/BKE_autoexec.h b/source/blender/blenkernel/BKE_autoexec.h
new file mode 100644
index 00000000000..7dc1e76ed5c
--- /dev/null
+++ b/source/blender/blenkernel/BKE_autoexec.h
@@ -0,0 +1,31 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Foundation 2013
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_AUTOEXEC_H__
+#define __BKE_AUTOEXEC_H__
+
+/** \file BKE_autoexec.h
+ * \ingroup bke
+ */
+
+bool BKE_autoexec_match(const char *path);
+
+#endif /* __BKE_AUTOEXEC_H__ */
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 6b9392a4169..3f3a5739d55 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -391,5 +391,30 @@ void modifier_mdef_compact_influences(struct ModifierData *md);
void modifier_path_init(char *path, int path_maxlen, const char *name);
const char *modifier_path_relbase(struct Object *ob);
+
+/* wrappers for modifier callbacks */
+
+struct DerivedMesh *modwrap_applyModifier(
+ ModifierData *md, struct Object *ob,
+ struct DerivedMesh *dm,
+ ModifierApplyFlag flag);
+
+struct DerivedMesh *modwrap_applyModifierEM(
+ ModifierData *md, struct Object *ob,
+ struct BMEditMesh *em,
+ struct DerivedMesh *dm,
+ ModifierApplyFlag flag);
+
+void modwrap_deformVerts(
+ ModifierData *md, struct Object *ob,
+ struct DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts,
+ ModifierApplyFlag flag);
+
+void modwrap_deformVertsEM(
+ ModifierData *md, struct Object *ob,
+ struct BMEditMesh *em, struct DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts);
+
#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 3864fe3b350..7e1355b5421 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -63,6 +63,7 @@ set(SRC
intern/anim.c
intern/anim_sys.c
intern/armature.c
+ intern/autoexec.c
intern/blender.c
intern/bmfont.c
intern/boids.c
@@ -163,6 +164,7 @@ set(SRC
BKE_anim.h
BKE_animsys.h
BKE_armature.h
+ BKE_autoexec.h
BKE_blender.h
BKE_bmesh.h
BKE_bmfont.h
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 6a21f33ac15..96ccc5be8e0 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -845,69 +845,6 @@ DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3])
return dm;
}
-/***/
-
-/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
-
-static DerivedMesh *modwrap_applyModifier(
- ModifierData *md, Object *ob,
- DerivedMesh *dm,
- ModifierApplyFlag flag)
-{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
-
- if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
- DM_ensure_normals(dm);
- }
- return mti->applyModifier(md, ob, dm, flag);
-}
-
-static DerivedMesh *modwrap_applyModifierEM(
- ModifierData *md, Object *ob,
- BMEditMesh *em,
- DerivedMesh *dm,
- ModifierApplyFlag flag)
-{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
-
- if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
- DM_ensure_normals(dm);
- }
- return mti->applyModifierEM(md, ob, em, dm, flag);
-}
-
-static void modwrap_deformVerts(
- ModifierData *md, Object *ob,
- DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts,
- ModifierApplyFlag flag)
-{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
-
- if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
- DM_ensure_normals(dm);
- }
- mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag);
-}
-
-static void modwrap_deformVertsEM(
- ModifierData *md, Object *ob,
- BMEditMesh *em, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts)
-{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
-
- if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
- DM_ensure_normals(dm);
- }
- mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts);
-}
-/* end modifier callback wrappers */
-
DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
ModifierData *md, int build_shapekey_layers)
{
@@ -2148,7 +2085,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
if (mti->applyModifierEM)
ndm = modwrap_applyModifierEM(md, ob, em, dm, MOD_APPLY_USECACHE);
else
- ndm = mti->applyModifier(md, ob, dm, MOD_APPLY_USECACHE);
+ ndm = modwrap_applyModifier(md, ob, dm, MOD_APPLY_USECACHE);
if (ndm) {
if (dm && dm != ndm)
diff --git a/source/blender/blenkernel/intern/autoexec.c b/source/blender/blenkernel/intern/autoexec.c
new file mode 100644
index 00000000000..c27343bf80a
--- /dev/null
+++ b/source/blender/blenkernel/intern/autoexec.c
@@ -0,0 +1,70 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Foundation 2013
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/armature.c
+ * \ingroup bke
+ *
+ * Currently just checks if a blend file can be trusted to autoexec,
+ * may add signing here later.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "DNA_userdef_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_fnmatch.h"
+#include "BLI_string.h"
+#include "BLI_path_util.h"
+
+#include "BKE_autoexec.h" /* own include */
+
+/**
+ * \param path The path to check against.
+ * \return Success
+ */
+bool BKE_autoexec_match(const char *path)
+{
+ bPathCompare *path_cmp;
+
+#ifdef WIN32
+ const int fnmatch_flags = FNM_CASEFOLD;
+#else
+ const int fnmatch_flags = 0;
+#endif
+
+ BLI_assert((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0);
+
+ for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) {
+ if ((path_cmp->flag & USER_PATHCMP_GLOB)) {
+ if (fnmatch(path_cmp->path, path, fnmatch_flags) == 0) {
+ return true;
+ }
+ }
+ else if (BLI_path_ncmp(path_cmp->path, path, strlen(path_cmp->path)) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 87a8def52bf..1e7aba6d25b 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -416,6 +416,8 @@ void BKE_userdef_free(void)
MEM_freeN(addon);
}
+ BLI_freelistN(&U.autoexec_paths);
+
BLI_freelistN(&U.uistyles);
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index f3de4001dea..e1ecf00104a 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -976,7 +976,6 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
dm = tdm;
CDDM_apply_vert_coords(dm, vertCos);
- CDDM_calc_normals_mapping(dm);
}
}
else {
@@ -989,8 +988,6 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
}
dm = CDDM_from_curve_displist(ob, dispbase);
-
- CDDM_calc_normals_mapping(dm);
}
if (vertCos) {
@@ -1001,7 +998,8 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
if (useCache)
appf |= MOD_APPLY_USECACHE;
- ndm = mti->applyModifier(md, ob, dm, appf);
+
+ ndm = modwrap_applyModifier(md, ob, dm, appf);
if (ndm) {
/* Modifier returned a new derived mesh */
@@ -1031,8 +1029,19 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
}
if (derivedFinal) {
- if (dm)
- DM_ensure_tessface(dm); /* needed for drawing */
+ if (dm) {
+ /* see: mesh_calc_modifiers */
+ if (dm->getNumTessFaces(dm) == 0) {
+ dm->recalcTessellation(dm);
+ }
+ /* Even if tessellation is not needed, some modifiers might have modified CD layers
+ * (like mloopcol or mloopuv), hence we have to update those. */
+ else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) {
+ DM_update_tessface_data(dm);
+ }
+
+ CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
+ }
(*derivedFinal) = dm;
}
@@ -1169,7 +1178,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina
if (!orcodm)
orcodm = create_orco_dm(scene, ob);
- ndm = mti->applyModifier(md, ob, orcodm, app_flag);
+ ndm = modwrap_applyModifier(md, ob, orcodm, app_flag);
if (ndm) {
/* if the modifier returned a new dm, release the old one */
diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c
index 979a38f0346..160972889fd 100644
--- a/source/blender/blenkernel/intern/editmesh_bvh.c
+++ b/source/blender/blenkernel/intern/editmesh_bvh.c
@@ -382,7 +382,7 @@ static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float *U
bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage);
for (i = 0; i < 3; i++) {
- dist = len_v3v3(hit->co, tri_cos[i]);
+ dist = len_squared_v3v3(hit->co, tri_cos[i]);
if (dist < hit->dist && dist < maxdist) {
copy_v3_v3(hit->co, tri_cos[i]);
/* XXX, normal ignores cage */
@@ -398,17 +398,17 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const
{
BVHTreeNearest hit;
struct VertSearchUserData bmcb_data;
+ const float maxdist_sq = maxdist * maxdist;
if (bmtree->cos_cage) BLI_assert(!(bmtree->em->bm->elem_index_dirty & BM_VERT));
copy_v3_v3(hit.co, co);
- /* XXX, why x5, scampbell */
- hit.dist = maxdist * 5;
+ hit.dist = maxdist_sq;
hit.index = -1;
bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->em->looptris;
bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage;
- bmcb_data.maxdist = maxdist;
+ bmcb_data.maxdist = maxdist_sq;
BLI_bvhtree_find_nearest(bmtree->tree, co, &hit, bmbvh_find_vert_closest_cb, &bmcb_data);
if (hit.dist != FLT_MAX && hit.index != -1) {
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 43819e1e80e..0546c85db67 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -112,19 +112,6 @@ typedef struct intlists { /* list of list of integers */
struct intlists *next; /* remaining elements */
} INTLISTS;
-typedef struct process { /* parameters, function, storage */
- /* what happens here? floats, I think. */
- /* float (*function)(void); */ /* implicit surface function */
- float (*function)(float, float, float);
- float size, delta; /* cube size, normal delta */
- int bounds; /* cube range within lattice */
- CUBES *cubes; /* active cubes */
- VERTICES vertices; /* surface vertices */
- CENTERLIST **centers; /* cube center hash table */
- CORNER **corners; /* corner value hash table */
- EDGELIST **edges; /* edge and vertex id hash table */
-} PROCESS;
-
/* dividing scene using octal tree makes polygonisation faster */
typedef struct ml_pointer {
struct ml_pointer *next, *prev;
@@ -153,20 +140,41 @@ struct pgn_elements {
char *data;
};
-/* Forward declarations */
-static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb);
-static int setcenter(CENTERLIST *table[], const int i, const int j, const int k);
-static CORNER *setcorner(PROCESS *p, int i, int j, int k);
-static void converge(const float p1[3], const float p2[3], float v1, float v2,
- float (*function)(float, float, float), float p[3], MetaBall *mb, int f);
-
-/* Global variables */
-static struct {
+typedef struct process { /* parameters, function, storage */
+ /* ** old G_mb contents ** */
float thresh;
int totelem;
MetaElem **mainb;
octal_tree *metaball_tree;
-} G_mb = {0};
+
+ /* ** old process contents ** */
+
+ /* what happens here? floats, I think. */
+ /* float (*function)(void); */ /* implicit surface function */
+ float (*function)(struct process*, float, float, float);
+ float size, delta; /* cube size, normal delta */
+ int bounds; /* cube range within lattice */
+ CUBES *cubes; /* active cubes */
+ VERTICES vertices; /* surface vertices */
+ CENTERLIST **centers; /* cube center hash table */
+ CORNER **corners; /* corner value hash table */
+ EDGELIST **edges; /* edge and vertex id hash table */
+
+ /* Runtime things */
+ int *indices;
+ int totindex, curindex;
+
+ int pgn_offset;
+ struct pgn_elements *pgn_current;
+ ListBase pgn_list;
+} PROCESS;
+
+/* Forward declarations */
+static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2, MetaBall *mb);
+static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k);
+static CORNER *setcorner(PROCESS *process, int i, int j, int k);
+static void converge(PROCESS *process, const float p1[3], const float p2[3], float v1, float v2,
+ float p[3], MetaBall *mb, int f);
/* Functions */
@@ -519,43 +527,23 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
Scene *sce_iter = scene;
Base *base;
Object *ob, *bob = basis;
- MetaElem *ml = NULL;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
- G_mb.totelem = 0;
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
return NULL;
-
+
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
-
if (ob->type == OB_MBALL) {
- if (ob == bob) {
- MetaBall *mb = ob->data;
-
- /* if bob object is in edit mode, then dynamic list of all MetaElems
- * is stored in editelems */
- if (mb->editelems) ml = mb->editelems->first;
- /* if bob object is in object mode */
- else ml = mb->elems.first;
- }
- else {
+ if (ob != bob) {
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
/* object ob has to be in same "group" ... it means, that it has to have
* same base of its name */
if (strcmp(obname, basisname) == 0) {
- MetaBall *mb = ob->data;
-
- /* if object is in edit mode, then dynamic list of all MetaElems
- * is stored in editelems */
- if (mb->editelems) ml = mb->editelems->first;
- /* if bob object is in object mode */
- else ml = mb->elems.first;
-
if (obnr < basisnr) {
if (!(ob->flag & OB_FROMDUPLI)) {
basis = ob;
@@ -564,12 +552,6 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
}
}
}
-
- for ( ; ml; ml = ml->next) {
- if (!(ml->flag & MB_HIDE)) {
- G_mb.totelem++;
- }
- }
}
}
@@ -768,60 +750,57 @@ static octal_node *find_metaball_octal_node(octal_node *node, float x, float y,
return node;
}
-static float metaball(float x, float y, float z)
+static float metaball(PROCESS *process, float x, float y, float z)
/* float x, y, z; */
{
+ octal_tree *metaball_tree = process->metaball_tree;
struct octal_node *node;
struct ml_pointer *ml_p;
float dens = 0;
int a;
- if (G_mb.totelem > 1) {
- node = find_metaball_octal_node(G_mb.metaball_tree->first, x, y, z, G_mb.metaball_tree->depth);
+ if (process->totelem > 1) {
+ node = find_metaball_octal_node(metaball_tree->first, x, y, z, metaball_tree->depth);
if (node) {
for (ml_p = node->elems.first; ml_p; ml_p = ml_p->next) {
dens += densfunc(ml_p->ml, x, y, z);
}
- dens += -0.5f * (G_mb.metaball_tree->pos - node->pos);
- dens += 0.5f * (G_mb.metaball_tree->neg - node->neg);
+ dens += -0.5f * (metaball_tree->pos - node->pos);
+ dens += 0.5f * (metaball_tree->neg - node->neg);
}
else {
- for (a = 0; a < G_mb.totelem; a++) {
- dens += densfunc(G_mb.mainb[a], x, y, z);
+ for (a = 0; a < process->totelem; a++) {
+ dens += densfunc(process->mainb[a], x, y, z);
}
}
}
else {
- dens += densfunc(G_mb.mainb[0], x, y, z);
+ dens += densfunc(process->mainb[0], x, y, z);
}
- return G_mb.thresh - dens;
+ return process->thresh - dens;
}
/* ******************************************** */
-static int *indices = NULL;
-static int totindex, curindex;
-
-
-static void accum_mballfaces(int i1, int i2, int i3, int i4)
+static void accum_mballfaces(PROCESS *process, int i1, int i2, int i3, int i4)
{
int *newi, *cur;
/* static int i = 0; I would like to delete altogether, but I don't dare to, yet */
- if (totindex == curindex) {
- totindex += 256;
- newi = MEM_mallocN(4 * sizeof(int) * totindex, "vertindex");
+ if (process->totindex == process->curindex) {
+ process->totindex += 256;
+ newi = MEM_mallocN(4 * sizeof(int) * process->totindex, "vertindex");
- if (indices) {
- memcpy(newi, indices, 4 * sizeof(int) * (totindex - 256));
- MEM_freeN(indices);
+ if (process->indices) {
+ memcpy(newi, process->indices, 4 * sizeof(int) * (process->totindex - 256));
+ MEM_freeN(process->indices);
}
- indices = newi;
+ process->indices = newi;
}
- cur = indices + 4 * curindex;
+ cur = process->indices + 4 * process->curindex;
/* displists now support array drawing, we treat tri's as fake quad */
@@ -833,63 +812,62 @@ static void accum_mballfaces(int i1, int i2, int i3, int i4)
else
cur[3] = i4;
- curindex++;
+ process->curindex++;
}
/* ******************* MEMORY MANAGEMENT *********************** */
-static void *new_pgn_element(int size)
+static void *new_pgn_element(PROCESS *process, int size)
{
/* during polygonize 1000s of elements are allocated
* and never freed in between. Freeing only done at the end.
*/
int blocksize = 16384;
- static int offs = 0; /* the current free address */
- static struct pgn_elements *cur = NULL;
- static ListBase lb = {NULL, NULL};
void *adr;
if (size > 10000 || size == 0) {
printf("incorrect use of new_pgn_element\n");
}
else if (size == -1) {
- cur = lb.first;
+ struct pgn_elements *cur = process->pgn_list.first;
while (cur) {
MEM_freeN(cur->data);
cur = cur->next;
}
- BLI_freelistN(&lb);
+ BLI_freelistN(&process->pgn_list);
return NULL;
}
size = 4 * ( (size + 3) / 4);
- if (cur) {
- if (size + offs < blocksize) {
- adr = (void *) (cur->data + offs);
- offs += size;
+ if (process->pgn_current) {
+ if (size + process->pgn_offset < blocksize) {
+ adr = (void *) (process->pgn_current->data + process->pgn_offset);
+ process->pgn_offset += size;
return adr;
}
}
- cur = MEM_callocN(sizeof(struct pgn_elements), "newpgn");
- cur->data = MEM_callocN(blocksize, "newpgn");
- BLI_addtail(&lb, cur);
+ process->pgn_current = MEM_callocN(sizeof(struct pgn_elements), "newpgn");
+ process->pgn_current->data = MEM_callocN(blocksize, "newpgn");
+ BLI_addtail(&process->pgn_list, process->pgn_current);
- offs = size;
- return cur->data;
+ process->pgn_offset = size;
+ return process->pgn_current->data;
}
-static void freepolygonize(PROCESS *p)
+static void freepolygonize(PROCESS *process)
{
- MEM_freeN(p->corners);
- MEM_freeN(p->edges);
- MEM_freeN(p->centers);
+ MEM_freeN(process->corners);
+ MEM_freeN(process->edges);
+ MEM_freeN(process->centers);
- new_pgn_element(-1);
-
- if (p->vertices.ptr) MEM_freeN(p->vertices.ptr);
+ new_pgn_element(process, -1);
+
+ if (process->vertices.ptr) {
+ MEM_freeN(process->vertices.ptr);
+ }
}
/**** Cubical Polygonization (optional) ****/
@@ -928,7 +906,7 @@ static int rightface[12] = {
/* docube: triangulate the cube directly, without decomposition */
-static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
+static void docube(PROCESS *process, CUBE *cube, MetaBall *mb)
{
INTLISTS *polys;
CORNER *c1, *c2;
@@ -945,45 +923,45 @@ static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
c1 = cube->corners[corner1[edges->i]];
c2 = cube->corners[corner2[edges->i]];
- indexar[count] = vertid(c1, c2, p, mb);
+ indexar[count] = vertid(process, c1, c2, mb);
count++;
}
if (count > 2) {
switch (count) {
case 3:
- accum_mballfaces(indexar[2], indexar[1], indexar[0], 0);
+ accum_mballfaces(process, indexar[2], indexar[1], indexar[0], 0);
break;
case 4:
- if (indexar[0] == 0) accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- else accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
+ if (indexar[0] == 0) accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ else accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
break;
case 5:
- if (indexar[0] == 0) accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- else accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
+ if (indexar[0] == 0) accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ else accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[4], indexar[3], indexar[0], 0);
+ accum_mballfaces(process, indexar[4], indexar[3], indexar[0], 0);
break;
case 6:
if (indexar[0] == 0) {
- accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- accum_mballfaces(indexar[0], indexar[5], indexar[4], indexar[3]);
+ accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ accum_mballfaces(process, indexar[0], indexar[5], indexar[4], indexar[3]);
}
else {
- accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[5], indexar[4], indexar[3], indexar[0]);
+ accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
+ accum_mballfaces(process, indexar[5], indexar[4], indexar[3], indexar[0]);
}
break;
case 7:
if (indexar[0] == 0) {
- accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- accum_mballfaces(indexar[0], indexar[5], indexar[4], indexar[3]);
+ accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ accum_mballfaces(process, indexar[0], indexar[5], indexar[4], indexar[3]);
}
else {
- accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[5], indexar[4], indexar[3], indexar[0]);
+ accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
+ accum_mballfaces(process, indexar[5], indexar[4], indexar[3], indexar[0]);
}
- accum_mballfaces(indexar[6], indexar[5], indexar[0], 0);
+ accum_mballfaces(process, indexar[6], indexar[5], indexar[0], 0);
break;
}
@@ -996,10 +974,10 @@ static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
* if surface crosses face, compute other four corners of adjacent cube
* and add new cube to cube stack */
-static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, int c3, int c4, PROCESS *p)
+static void testface(PROCESS *process, int i, int j, int k, CUBE *old, int bit, int c1, int c2, int c3, int c4)
{
CUBE newc;
- CUBES *oldcubes = p->cubes;
+ CUBES *oldcubes = process->cubes;
CORNER *corn1, *corn2, *corn3, *corn4;
int n, pos;
@@ -1015,12 +993,13 @@ static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, in
/* test if cube out of bounds */
/*if ( abs(i) > p->bounds || abs(j) > p->bounds || abs(k) > p->bounds) return;*/
/* test if already visited (always as last) */
- if (setcenter(p->centers, i, j, k)) return;
-
+ if (setcenter(process, process->centers, i, j, k)) {
+ return;
+ }
/* create new cube and add cube to top of stack: */
- p->cubes = (CUBES *) new_pgn_element(sizeof(CUBES));
- p->cubes->next = oldcubes;
+ process->cubes = (CUBES *) new_pgn_element(process, sizeof(CUBES));
+ process->cubes->next = oldcubes;
newc.i = i;
newc.j = j;
@@ -1032,22 +1011,22 @@ static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, in
newc.corners[FLIP(c3, bit)] = corn3;
newc.corners[FLIP(c4, bit)] = corn4;
- if (newc.corners[0] == NULL) newc.corners[0] = setcorner(p, i, j, k);
- if (newc.corners[1] == NULL) newc.corners[1] = setcorner(p, i, j, k + 1);
- if (newc.corners[2] == NULL) newc.corners[2] = setcorner(p, i, j + 1, k);
- if (newc.corners[3] == NULL) newc.corners[3] = setcorner(p, i, j + 1, k + 1);
- if (newc.corners[4] == NULL) newc.corners[4] = setcorner(p, i + 1, j, k);
- if (newc.corners[5] == NULL) newc.corners[5] = setcorner(p, i + 1, j, k + 1);
- if (newc.corners[6] == NULL) newc.corners[6] = setcorner(p, i + 1, j + 1, k);
- if (newc.corners[7] == NULL) newc.corners[7] = setcorner(p, i + 1, j + 1, k + 1);
+ if (newc.corners[0] == NULL) newc.corners[0] = setcorner(process, i, j, k);
+ if (newc.corners[1] == NULL) newc.corners[1] = setcorner(process, i, j, k + 1);
+ if (newc.corners[2] == NULL) newc.corners[2] = setcorner(process, i, j + 1, k);
+ if (newc.corners[3] == NULL) newc.corners[3] = setcorner(process, i, j + 1, k + 1);
+ if (newc.corners[4] == NULL) newc.corners[4] = setcorner(process, i + 1, j, k);
+ if (newc.corners[5] == NULL) newc.corners[5] = setcorner(process, i + 1, j, k + 1);
+ if (newc.corners[6] == NULL) newc.corners[6] = setcorner(process, i + 1, j + 1, k);
+ if (newc.corners[7] == NULL) newc.corners[7] = setcorner(process, i + 1, j + 1, k + 1);
- p->cubes->cube = newc;
+ process->cubes->cube = newc;
}
/* setcorner: return corner with the given lattice location
* set (and cache) its function value */
-static CORNER *setcorner(PROCESS *p, int i, int j, int k)
+static CORNER *setcorner(PROCESS *process, int i, int j, int k)
{
/* for speed, do corner value caching here */
CORNER *c;
@@ -1055,7 +1034,7 @@ static CORNER *setcorner(PROCESS *p, int i, int j, int k)
/* does corner exist? */
index = HASH(i, j, k);
- c = p->corners[index];
+ c = process->corners[index];
for (; c != NULL; c = c->next) {
if (c->i == i && c->j == j && c->k == k) {
@@ -1063,18 +1042,18 @@ static CORNER *setcorner(PROCESS *p, int i, int j, int k)
}
}
- c = (CORNER *) new_pgn_element(sizeof(CORNER));
+ c = (CORNER *) new_pgn_element(process, sizeof(CORNER));
c->i = i;
- c->co[0] = ((float)i - 0.5f) * p->size;
+ c->co[0] = ((float)i - 0.5f) * process->size;
c->j = j;
- c->co[1] = ((float)j - 0.5f) * p->size;
+ c->co[1] = ((float)j - 0.5f) * process->size;
c->k = k;
- c->co[2] = ((float)k - 0.5f) * p->size;
- c->value = p->function(c->co[0], c->co[1], c->co[2]);
+ c->co[2] = ((float)k - 0.5f) * process->size;
+ c->value = process->function(process, c->co[0], c->co[1], c->co[2]);
- c->next = p->corners[index];
- p->corners[index] = c;
+ c->next = process->corners[index];
+ process->corners[index] = c;
return c;
}
@@ -1196,7 +1175,7 @@ void BKE_mball_cubeTable_free(void)
/* setcenter: set (i, j, k) entry of table[]
* return 1 if already set; otherwise, set and return 0 */
-static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
+static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k)
{
int index;
CENTERLIST *newc, *l, *q;
@@ -1208,7 +1187,7 @@ static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
if (l->i == i && l->j == j && l->k == k) return 1;
}
- newc = (CENTERLIST *) new_pgn_element(sizeof(CENTERLIST));
+ newc = (CENTERLIST *) new_pgn_element(process, sizeof(CENTERLIST));
newc->i = i;
newc->j = j;
newc->k = k;
@@ -1221,7 +1200,8 @@ static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
/* setedge: set vertex id for edge */
-static void setedge(EDGELIST *table[],
+static void setedge(PROCESS *process,
+ EDGELIST *table[],
int i1, int j1,
int k1, int i2,
int j2, int k2,
@@ -1242,7 +1222,7 @@ static void setedge(EDGELIST *table[],
k2 = t;
}
index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
- newe = (EDGELIST *) new_pgn_element(sizeof(EDGELIST));
+ newe = (EDGELIST *) new_pgn_element(process, sizeof(EDGELIST));
newe->i1 = i1;
newe->j1 = j1;
newe->k1 = k1;
@@ -1316,14 +1296,14 @@ static void addtovertices(VERTICES *vertices, VERTEX v)
/* vnormal: compute unit length surface normal at point */
-static void vnormal(const float point[3], PROCESS *p, float r_no[3])
+static void vnormal(PROCESS *process, const float point[3], float r_no[3])
{
- const float delta = 0.2f * p->delta;
- const float f = p->function(point[0], point[1], point[2]);
+ const float delta = 0.2f * process->delta;
+ const float f = process->function(process, point[0], point[1], point[2]);
- r_no[0] = p->function(point[0] + delta, point[1], point[2]) - f;
- r_no[1] = p->function(point[0], point[1] + delta, point[2]) - f;
- r_no[2] = p->function(point[0], point[1], point[2] + delta) - f;
+ r_no[0] = process->function(process, point[0] + delta, point[1], point[2]) - f;
+ r_no[1] = process->function(process, point[0], point[1] + delta, point[2]) - f;
+ r_no[2] = process->function(process, point[0], point[1], point[2] + delta) - f;
#if 1
normalize_v3(r_no);
@@ -1335,11 +1315,11 @@ static void vnormal(const float point[3], PROCESS *p, float r_no[3])
delta *= 2.0f;
- f = p->function(point[0], point[1], point[2]);
+ f = process->function(process, point[0], point[1], point[2]);
- tvec[0] = p->function(point[0] + delta, point[1], point[2]) - f;
- tvec[1] = p->function(point[0], point[1] + delta, point[2]) - f;
- tvec[2] = p->function(point[0], point[1], point[2] + delta) - f;
+ tvec[0] = process->function(process, point[0] + delta, point[1], point[2]) - f;
+ tvec[1] = process->function(process, point[0], point[1] + delta, point[2]) - f;
+ tvec[2] = process->function(process, point[0], point[1], point[2] + delta) - f;
if (normalize_v3(tvec) != 0.0f) {
add_v3_v3(r_no, tvec);
@@ -1350,32 +1330,30 @@ static void vnormal(const float point[3], PROCESS *p, float r_no[3])
}
-static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb)
+static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2, MetaBall *mb)
{
VERTEX v;
- int vid = getedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
+ int vid = getedge(process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
if (vid != -1) {
return vid; /* previously computed */
}
- converge(c1->co, c2->co, c1->value, c2->value, p->function, v.co, mb, 1); /* position */
- vnormal(v.co, p, v.no);
+ converge(process, c1->co, c2->co, c1->value, c2->value, v.co, mb, 1); /* position */
+ vnormal(process, v.co, v.no);
- addtovertices(&p->vertices, v); /* save vertex */
- vid = p->vertices.count - 1;
- setedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
+ addtovertices(&process->vertices, v); /* save vertex */
+ vid = process->vertices.count - 1;
+ setedge(process, process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
return vid;
}
-
-
/* converge: from two points of differing sign, converge to zero crossing */
/* watch it: p1 and p2 are used to calculate */
-static void converge(const float p1[3], const float p2[3], float v1, float v2,
- float (*function)(float, float, float), float p[3], MetaBall *mb, int f)
+static void converge(PROCESS *process, const float p1[3], const float p2[3], float v1, float v2,
+ float p[3], MetaBall *mb, int f)
{
int i = 0;
float pos[3], neg[3];
@@ -1426,8 +1404,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[0] = 0.5f * (pos[0] + neg[0]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[0] = p[0];
- else neg[0] = p[0];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[0] = p[0];
+ else neg[0] = p[0];
}
}
@@ -1437,8 +1415,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[1] = 0.5f * (pos[1] + neg[1]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[1] = p[1];
- else neg[1] = p[1];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[1] = p[1];
+ else neg[1] = p[1];
}
}
@@ -1448,8 +1426,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[2] = 0.5f * (pos[2] + neg[2]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[2] = p[2];
- else neg[2] = p[2];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[2] = p[2];
+ else neg[2] = p[2];
}
}
@@ -1461,7 +1439,7 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
return;
}
- if ((function(p[0], p[1], p[2])) > 0.0f) {
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) {
copy_v3_v3(pos, &p[0]);
}
else {
@@ -1471,7 +1449,7 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
}
/* ************************************** */
-static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
+static void add_cube(PROCESS *process, int i, int j, int k, int count)
{
CUBES *ncube;
int n;
@@ -1483,11 +1461,11 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
for (b = j - 1; b < j + count; b++)
for (c = k - 1; c < k + count; c++) {
/* test if cube has been found before */
- if (setcenter(mbproc->centers, a, b, c) == 0) {
+ if (setcenter(process, process->centers, a, b, c) == 0) {
/* push cube on stack: */
- ncube = (CUBES *) new_pgn_element(sizeof(CUBES));
- ncube->next = mbproc->cubes;
- mbproc->cubes = ncube;
+ ncube = (CUBES *) new_pgn_element(process, sizeof(CUBES));
+ ncube->next = process->cubes;
+ process->cubes = ncube;
ncube->cube.i = a;
ncube->cube.j = b;
@@ -1495,18 +1473,18 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
/* set corners of initial cube: */
for (n = 0; n < 8; n++)
- ncube->cube.corners[n] = setcorner(mbproc, a + MB_BIT(n, 2), b + MB_BIT(n, 1), c + MB_BIT(n, 0));
+ ncube->cube.corners[n] = setcorner(process, a + MB_BIT(n, 2), b + MB_BIT(n, 1), c + MB_BIT(n, 0));
}
}
}
-static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
+static void find_first_points(PROCESS *process, MetaBall *mb, int a)
{
MetaElem *ml;
float f;
- ml = G_mb.mainb[a];
+ ml = process->mainb[a];
f = 1.0f - (mb->thresh / ml->s);
/* Skip, when Stiffness of MetaElement is too small ... MetaElement can't be
@@ -1521,7 +1499,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
float tmp_v, workp_v, max_len, nx, ny, nz, max_dim;
calc_mballco(ml, in);
- in_v = mbproc->function(in[0], in[1], in[2]);
+ in_v = process->function(process, in[0], in[1], in[2]);
for (i = 0; i < 3; i++) {
switch (ml->type) {
@@ -1566,16 +1544,16 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
calc_mballco(ml, out);
- /*out_v = mbproc->function(out[0], out[1], out[2]);*/ /*UNUSED*/
+ /*out_v = process->function(out[0], out[1], out[2]);*/ /*UNUSED*/
/* find "first points" on Implicit Surface of MetaElemnt ml */
copy_v3_v3(workp, in);
workp_v = in_v;
max_len = len_v3v3(out, in);
- nx = abs((out[0] - in[0]) / mbproc->size);
- ny = abs((out[1] - in[1]) / mbproc->size);
- nz = abs((out[2] - in[2]) / mbproc->size);
+ nx = abs((out[0] - in[0]) / process->size);
+ ny = abs((out[1] - in[1]) / process->size);
+ nz = abs((out[2] - in[2]) / process->size);
max_dim = max_fff(nx, ny, nz);
if (max_dim != 0.0f) {
@@ -1589,22 +1567,22 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
add_v3_v3(workp, dvec);
/* compute value of implicite function */
- tmp_v = mbproc->function(workp[0], workp[1], workp[2]);
+ tmp_v = process->function(process, workp[0], workp[1], workp[2]);
/* add cube to the stack, when value of implicite function crosses zero value */
if ((tmp_v < 0.0f && workp_v >= 0.0f) || (tmp_v > 0.0f && workp_v <= 0.0f)) {
/* indexes of CUBE, which includes "first point" */
- c_i = (int)floor(workp[0] / mbproc->size);
- c_j = (int)floor(workp[1] / mbproc->size);
- c_k = (int)floor(workp[2] / mbproc->size);
+ c_i = (int)floor(workp[0] / process->size);
+ c_j = (int)floor(workp[1] / process->size);
+ c_k = (int)floor(workp[2] / process->size);
/* add CUBE (with indexes c_i, c_j, c_k) to the stack,
* this cube includes found point of Implicit Surface */
if ((ml->flag & MB_NEGATIVE) == 0) {
- add_cube(mbproc, c_i, c_j, c_k, 1);
+ add_cube(process, c_i, c_j, c_k, 1);
}
else {
- add_cube(mbproc, c_i, c_j, c_k, 2);
+ add_cube(process, c_i, c_j, c_k, 2);
}
}
len = len_v3v3(workp, in);
@@ -1618,43 +1596,43 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
}
}
-static void polygonize(PROCESS *mbproc, MetaBall *mb)
+static void polygonize(PROCESS *process, MetaBall *mb)
{
CUBE c;
int a;
- mbproc->vertices.count = mbproc->vertices.max = 0;
- mbproc->vertices.ptr = NULL;
+ process->vertices.count = process->vertices.max = 0;
+ process->vertices.ptr = NULL;
/* allocate hash tables and build cube polygon table: */
- mbproc->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
- mbproc->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
- mbproc->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
+ process->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
+ process->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
+ process->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
makecubetable();
- for (a = 0; a < G_mb.totelem; a++) {
+ for (a = 0; a < process->totelem; a++) {
/* try to find 8 points on the surface for each MetaElem */
- find_first_points(mbproc, mb, a);
+ find_first_points(process, mb, a);
}
/* polygonize all MetaElems of current MetaBall */
- while (mbproc->cubes != NULL) { /* process active cubes till none left */
- c = mbproc->cubes->cube;
+ while (process->cubes != NULL) { /* process active cubes till none left */
+ c = process->cubes->cube;
/* polygonize the cube directly: */
- docube(&c, mbproc, mb);
+ docube(process, &c, mb);
/* pop current cube from stack */
- mbproc->cubes = mbproc->cubes->next;
+ process->cubes = process->cubes->next;
/* test six face directions, maybe add to stack: */
- testface(c.i - 1, c.j, c.k, &c, 2, LBN, LBF, LTN, LTF, mbproc);
- testface(c.i + 1, c.j, c.k, &c, 2, RBN, RBF, RTN, RTF, mbproc);
- testface(c.i, c.j - 1, c.k, &c, 1, LBN, LBF, RBN, RBF, mbproc);
- testface(c.i, c.j + 1, c.k, &c, 1, LTN, LTF, RTN, RTF, mbproc);
- testface(c.i, c.j, c.k - 1, &c, 0, LBN, LTN, RBN, RTN, mbproc);
- testface(c.i, c.j, c.k + 1, &c, 0, LBF, LTF, RBF, RTF, mbproc);
+ testface(process, c.i - 1, c.j, c.k, &c, 2, LBN, LBF, LTN, LTF);
+ testface(process, c.i + 1, c.j, c.k, &c, 2, RBN, RBF, RTN, RTF);
+ testface(process, c.i, c.j - 1, c.k, &c, 1, LBN, LBF, RBN, RBF);
+ testface(process, c.i, c.j + 1, c.k, &c, 1, LTN, LTF, RTN, RTF);
+ testface(process, c.i, c.j, c.k - 1, &c, 0, LBN, LTN, RBN, RTN);
+ testface(process, c.i, c.j, c.k + 1, &c, 0, LBF, LTF, RBF, RTF);
}
}
@@ -1666,7 +1644,7 @@ BLI_INLINE void copy_v3_fl3(float v[3], float x, float y, float z)
v[2] = z;
}
-static float init_meta(Scene *scene, Object *ob) /* return totsize */
+static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return totsize */
{
Scene *sce_iter = scene;
Base *base;
@@ -1733,7 +1711,7 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
ml_count++;
ml = ml->next;
}
- G_mb.totelem -= ml_count;
+ process->totelem -= ml_count;
}
else {
while (ml) {
@@ -1763,12 +1741,12 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
mul_m4_m4m4(temp1, temp2, temp3);
/* make a copy because of duplicates */
- G_mb.mainb[a] = new_pgn_element(sizeof(MetaElem));
- *(G_mb.mainb[a]) = *ml;
- G_mb.mainb[a]->bb = new_pgn_element(sizeof(BoundBox));
+ process->mainb[a] = new_pgn_element(process, sizeof(MetaElem));
+ *(process->mainb[a]) = *ml;
+ process->mainb[a]->bb = new_pgn_element(process, sizeof(BoundBox));
- mat = new_pgn_element(4 * 4 * sizeof(float));
- imat = new_pgn_element(4 * 4 * sizeof(float));
+ mat = new_pgn_element(process, 4 * 4 * sizeof(float));
+ imat = new_pgn_element(process, 4 * 4 * sizeof(float));
/* mat is the matrix to transform from mball into the basis-mball */
invert_m4_m4(obinv, obmat);
@@ -1778,10 +1756,10 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
invert_m4_m4(imat, mat);
- G_mb.mainb[a]->rad2 = ml->rad * ml->rad;
+ process->mainb[a]->rad2 = ml->rad * ml->rad;
- G_mb.mainb[a]->mat = (float *) mat;
- G_mb.mainb[a]->imat = (float *) imat;
+ process->mainb[a]->mat = (float *) mat;
+ process->mainb[a]->imat = (float *) imat;
if (!MB_TYPE_SIZE_SQUARED(ml->type)) {
expx = ml->expx;
@@ -1796,40 +1774,40 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
/* untransformed Bounding Box of MetaElem */
/* TODO, its possible the elem type has been changed and the exp* values can use a fallback */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[0], -expx, -expy, -expz); /* 0 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[1], +expx, -expy, -expz); /* 1 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[2], +expx, +expy, -expz); /* 2 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[3], -expx, +expy, -expz); /* 3 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[4], -expx, -expy, +expz); /* 4 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[5], +expx, -expy, +expz); /* 5 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[6], +expx, +expy, +expz); /* 6 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[7], -expx, +expy, +expz); /* 7 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[0], -expx, -expy, -expz); /* 0 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[1], +expx, -expy, -expz); /* 1 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[2], +expx, +expy, -expz); /* 2 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[3], -expx, +expy, -expz); /* 3 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[4], -expx, -expy, +expz); /* 4 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[5], +expx, -expy, +expz); /* 5 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[6], +expx, +expy, +expz); /* 6 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[7], -expx, +expy, +expz); /* 7 */
/* transformation of Metalem bb */
for (i = 0; i < 8; i++)
- mul_m4_v3((float (*)[4])mat, G_mb.mainb[a]->bb->vec[i]);
+ mul_m4_v3((float (*)[4])mat, process->mainb[a]->bb->vec[i]);
/* find max and min of transformed bb */
for (i = 0; i < 8; i++) {
/* find maximums */
- if (G_mb.mainb[a]->bb->vec[i][0] > max_x) max_x = G_mb.mainb[a]->bb->vec[i][0];
- if (G_mb.mainb[a]->bb->vec[i][1] > max_y) max_y = G_mb.mainb[a]->bb->vec[i][1];
- if (G_mb.mainb[a]->bb->vec[i][2] > max_z) max_z = G_mb.mainb[a]->bb->vec[i][2];
+ if (process->mainb[a]->bb->vec[i][0] > max_x) max_x = process->mainb[a]->bb->vec[i][0];
+ if (process->mainb[a]->bb->vec[i][1] > max_y) max_y = process->mainb[a]->bb->vec[i][1];
+ if (process->mainb[a]->bb->vec[i][2] > max_z) max_z = process->mainb[a]->bb->vec[i][2];
/* find minimums */
- if (G_mb.mainb[a]->bb->vec[i][0] < min_x) min_x = G_mb.mainb[a]->bb->vec[i][0];
- if (G_mb.mainb[a]->bb->vec[i][1] < min_y) min_y = G_mb.mainb[a]->bb->vec[i][1];
- if (G_mb.mainb[a]->bb->vec[i][2] < min_z) min_z = G_mb.mainb[a]->bb->vec[i][2];
+ if (process->mainb[a]->bb->vec[i][0] < min_x) min_x = process->mainb[a]->bb->vec[i][0];
+ if (process->mainb[a]->bb->vec[i][1] < min_y) min_y = process->mainb[a]->bb->vec[i][1];
+ if (process->mainb[a]->bb->vec[i][2] < min_z) min_z = process->mainb[a]->bb->vec[i][2];
}
/* create "new" bb, only point 0 and 6, which are
* necessary for octal tree filling */
- G_mb.mainb[a]->bb->vec[0][0] = min_x - ml->rad;
- G_mb.mainb[a]->bb->vec[0][1] = min_y - ml->rad;
- G_mb.mainb[a]->bb->vec[0][2] = min_z - ml->rad;
+ process->mainb[a]->bb->vec[0][0] = min_x - ml->rad;
+ process->mainb[a]->bb->vec[0][1] = min_y - ml->rad;
+ process->mainb[a]->bb->vec[0][2] = min_z - ml->rad;
- G_mb.mainb[a]->bb->vec[6][0] = max_x + ml->rad;
- G_mb.mainb[a]->bb->vec[6][1] = max_y + ml->rad;
- G_mb.mainb[a]->bb->vec[6][2] = max_z + ml->rad;
+ process->mainb[a]->bb->vec[6][0] = max_x + ml->rad;
+ process->mainb[a]->bb->vec[6][1] = max_y + ml->rad;
+ process->mainb[a]->bb->vec[6][2] = max_z + ml->rad;
a++;
}
@@ -1842,13 +1820,13 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
/* totsize (= 'manhattan' radius) */
totsize = 0.0;
- for (a = 0; a < G_mb.totelem; a++) {
+ for (a = 0; a < process->totelem; a++) {
- vec[0] = G_mb.mainb[a]->x + G_mb.mainb[a]->rad + G_mb.mainb[a]->expx;
- vec[1] = G_mb.mainb[a]->y + G_mb.mainb[a]->rad + G_mb.mainb[a]->expy;
- vec[2] = G_mb.mainb[a]->z + G_mb.mainb[a]->rad + G_mb.mainb[a]->expz;
+ vec[0] = process->mainb[a]->x + process->mainb[a]->rad + process->mainb[a]->expx;
+ vec[1] = process->mainb[a]->y + process->mainb[a]->rad + process->mainb[a]->expy;
+ vec[2] = process->mainb[a]->z + process->mainb[a]->rad + process->mainb[a]->expz;
- calc_mballco(G_mb.mainb[a], vec);
+ calc_mballco(process->mainb[a], vec);
size = fabsf(vec[0]);
if (size > totsize) totsize = size;
@@ -1857,11 +1835,11 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
size = fabsf(vec[2]);
if (size > totsize) totsize = size;
- vec[0] = G_mb.mainb[a]->x - G_mb.mainb[a]->rad;
- vec[1] = G_mb.mainb[a]->y - G_mb.mainb[a]->rad;
- vec[2] = G_mb.mainb[a]->z - G_mb.mainb[a]->rad;
+ vec[0] = process->mainb[a]->x - process->mainb[a]->rad;
+ vec[1] = process->mainb[a]->y - process->mainb[a]->rad;
+ vec[2] = process->mainb[a]->z - process->mainb[a]->rad;
- calc_mballco(G_mb.mainb[a], vec);
+ calc_mballco(process->mainb[a], vec);
size = fabsf(vec[0]);
if (size > totsize) totsize = size;
@@ -1871,8 +1849,8 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
if (size > totsize) totsize = size;
}
- for (a = 0; a < G_mb.totelem; a++) {
- G_mb.thresh += densfunc(G_mb.mainb[a], 2.0f * totsize, 2.0f * totsize, 2.0f * totsize);
+ for (a = 0; a < process->totelem; a++) {
+ process->thresh += densfunc(process->mainb[a], 2.0f * totsize, 2.0f * totsize, 2.0f * totsize);
}
return totsize;
@@ -2181,20 +2159,20 @@ static void free_metaball_octal_node(octal_node *node)
}
/* If scene include more than one MetaElem, then octree is used */
-static void init_metaball_octal_tree(int depth)
+static void init_metaball_octal_tree(PROCESS *process, int depth)
{
struct octal_node *node;
ml_pointer *ml_p;
float size[3];
int a;
- G_mb.metaball_tree = MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
- G_mb.metaball_tree->first = node = MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
+ process->metaball_tree = MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
+ process->metaball_tree->first = node = MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
/* maximal depth of octree */
- G_mb.metaball_tree->depth = depth;
+ process->metaball_tree->depth = depth;
- G_mb.metaball_tree->neg = node->neg = 0;
- G_mb.metaball_tree->pos = node->pos = 0;
+ process->metaball_tree->neg = node->neg = 0;
+ process->metaball_tree->pos = node->pos = 0;
node->elems.first = NULL;
node->elems.last = NULL;
@@ -2207,26 +2185,26 @@ static void init_metaball_octal_tree(int depth)
node->x_max = node->y_max = node->z_max = -FLT_MAX;
/* size of octal tree scene */
- for (a = 0; a < G_mb.totelem; a++) {
- if (G_mb.mainb[a]->bb->vec[0][0] < node->x_min) node->x_min = G_mb.mainb[a]->bb->vec[0][0];
- if (G_mb.mainb[a]->bb->vec[0][1] < node->y_min) node->y_min = G_mb.mainb[a]->bb->vec[0][1];
- if (G_mb.mainb[a]->bb->vec[0][2] < node->z_min) node->z_min = G_mb.mainb[a]->bb->vec[0][2];
+ for (a = 0; a < process->totelem; a++) {
+ if (process->mainb[a]->bb->vec[0][0] < node->x_min) node->x_min = process->mainb[a]->bb->vec[0][0];
+ if (process->mainb[a]->bb->vec[0][1] < node->y_min) node->y_min = process->mainb[a]->bb->vec[0][1];
+ if (process->mainb[a]->bb->vec[0][2] < node->z_min) node->z_min = process->mainb[a]->bb->vec[0][2];
- if (G_mb.mainb[a]->bb->vec[6][0] > node->x_max) node->x_max = G_mb.mainb[a]->bb->vec[6][0];
- if (G_mb.mainb[a]->bb->vec[6][1] > node->y_max) node->y_max = G_mb.mainb[a]->bb->vec[6][1];
- if (G_mb.mainb[a]->bb->vec[6][2] > node->z_max) node->z_max = G_mb.mainb[a]->bb->vec[6][2];
+ if (process->mainb[a]->bb->vec[6][0] > node->x_max) node->x_max = process->mainb[a]->bb->vec[6][0];
+ if (process->mainb[a]->bb->vec[6][1] > node->y_max) node->y_max = process->mainb[a]->bb->vec[6][1];
+ if (process->mainb[a]->bb->vec[6][2] > node->z_max) node->z_max = process->mainb[a]->bb->vec[6][2];
ml_p = MEM_mallocN(sizeof(ml_pointer), "ml_pointer");
- ml_p->ml = G_mb.mainb[a];
+ ml_p->ml = process->mainb[a];
BLI_addtail(&node->elems, ml_p);
- if ((G_mb.mainb[a]->flag & MB_NEGATIVE) == 0) {
+ if ((process->mainb[a]->flag & MB_NEGATIVE) == 0) {
/* number of positive MetaElem in scene */
- G_mb.metaball_tree->pos++;
+ process->metaball_tree->pos++;
}
else {
/* number of negative MetaElem in scene */
- G_mb.metaball_tree->neg++;
+ process->metaball_tree->neg++;
}
}
@@ -2236,61 +2214,106 @@ static void init_metaball_octal_tree(int depth)
size[2] = node->z_max - node->z_min;
/* first node is subdivided recursively */
- subdivide_metaball_octal_node(node, size[0], size[1], size[2], G_mb.metaball_tree->depth);
+ subdivide_metaball_octal_node(node, size[0], size[1], size[2], process->metaball_tree->depth);
+}
+
+static void mball_count(PROCESS *process, Scene *scene, Object *basis)
+{
+ Scene *sce_iter = scene;
+ Base *base;
+ Object *ob, *bob = basis;
+ MetaElem *ml = NULL;
+ int basisnr, obnr;
+ char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
+
+ BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
+ process->totelem = 0;
+
+ /* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
+ if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
+ return;
+
+ while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
+ if (ob->type == OB_MBALL) {
+ if (ob == bob) {
+ MetaBall *mb = ob->data;
+
+ /* if bob object is in edit mode, then dynamic list of all MetaElems
+ * is stored in editelems */
+ if (mb->editelems) ml = mb->editelems->first;
+ /* if bob object is in object mode */
+ else ml = mb->elems.first;
+ }
+ else {
+ BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
+
+ /* object ob has to be in same "group" ... it means, that it has to have
+ * same base of its name */
+ if (strcmp(obname, basisname) == 0) {
+ MetaBall *mb = ob->data;
+
+ /* if object is in edit mode, then dynamic list of all MetaElems
+ * is stored in editelems */
+ if (mb->editelems) ml = mb->editelems->first;
+ /* if bob object is in object mode */
+ else ml = mb->elems.first;
+ }
+ }
+
+ for ( ; ml; ml = ml->next) {
+ if (!(ml->flag & MB_HIDE)) {
+ process->totelem++;
+ }
+ }
+ }
+ }
}
void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
{
- PROCESS mbproc;
MetaBall *mb;
DispList *dl;
int a, nr_cubes;
float *co, *no, totsize, width;
+ PROCESS process = {0};
mb = ob->data;
- if (G_mb.totelem == 0) return;
+ mball_count(&process, scene, ob);
+
+ if (process.totelem == 0) return;
if ((G.is_rendering == FALSE) && (mb->flag == MB_UPDATE_NEVER)) return;
if (G.moving && mb->flag == MB_UPDATE_FAST) return;
- curindex = totindex = 0;
- indices = NULL;
- G_mb.thresh = mb->thresh;
+ process.thresh = mb->thresh;
/* total number of MetaElems (totelem) is precomputed in find_basis_mball() function */
- G_mb.mainb = MEM_mallocN(sizeof(void *) * G_mb.totelem, "mainb");
+ process.mainb = MEM_mallocN(sizeof(void *) * process.totelem, "mainb");
/* initialize all mainb (MetaElems) */
- totsize = init_meta(scene, ob);
-
- if (G_mb.metaball_tree) {
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
- }
+ totsize = init_meta(&process, scene, ob);
/* if scene includes more than one MetaElem, then octal tree optimization is used */
- if ((G_mb.totelem > 1) && (G_mb.totelem <= 64)) init_metaball_octal_tree(1);
- if ((G_mb.totelem > 64) && (G_mb.totelem <= 128)) init_metaball_octal_tree(2);
- if ((G_mb.totelem > 128) && (G_mb.totelem <= 512)) init_metaball_octal_tree(3);
- if ((G_mb.totelem > 512) && (G_mb.totelem <= 1024)) init_metaball_octal_tree(4);
- if (G_mb.totelem > 1024) init_metaball_octal_tree(5);
+ if ((process.totelem > 1) && (process.totelem <= 64)) init_metaball_octal_tree(&process, 1);
+ if ((process.totelem > 64) && (process.totelem <= 128)) init_metaball_octal_tree(&process, 2);
+ if ((process.totelem > 128) && (process.totelem <= 512)) init_metaball_octal_tree(&process, 3);
+ if ((process.totelem > 512) && (process.totelem <= 1024)) init_metaball_octal_tree(&process, 4);
+ if (process.totelem > 1024) init_metaball_octal_tree(&process, 5);
/* don't polygonize metaballs with too high resolution (base mball to small)
* note: Eps was 0.0001f but this was giving problems for blood animation for durian, using 0.00001f */
- if (G_mb.metaball_tree) {
- if (ob->size[0] <= 0.00001f * (G_mb.metaball_tree->first->x_max - G_mb.metaball_tree->first->x_min) ||
- ob->size[1] <= 0.00001f * (G_mb.metaball_tree->first->y_max - G_mb.metaball_tree->first->y_min) ||
- ob->size[2] <= 0.00001f * (G_mb.metaball_tree->first->z_max - G_mb.metaball_tree->first->z_min))
+ if (process.metaball_tree) {
+ if (ob->size[0] <= 0.00001f * (process.metaball_tree->first->x_max - process.metaball_tree->first->x_min) ||
+ ob->size[1] <= 0.00001f * (process.metaball_tree->first->y_max - process.metaball_tree->first->y_min) ||
+ ob->size[2] <= 0.00001f * (process.metaball_tree->first->z_max - process.metaball_tree->first->z_min))
{
- new_pgn_element(-1); /* free values created by init_meta */
+ new_pgn_element(&process, -1); /* free values created by init_meta */
- MEM_freeN(G_mb.mainb);
+ MEM_freeN(process.mainb);
/* free tree */
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
+ free_metaball_octal_node(process.metaball_tree->first);
+ MEM_freeN(process.metaball_tree);
return;
}
@@ -2308,46 +2331,46 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
nr_cubes = (int)(0.5f + totsize / width);
/* init process */
- mbproc.function = metaball;
- mbproc.size = width;
- mbproc.bounds = nr_cubes;
- mbproc.cubes = NULL;
- mbproc.delta = width / (float)(RES * RES);
+ process.function = metaball;
+ process.size = width;
+ process.bounds = nr_cubes;
+ process.cubes = NULL;
+ process.delta = width / (float)(RES * RES);
- polygonize(&mbproc, mb);
+ polygonize(&process, mb);
- MEM_freeN(G_mb.mainb);
+ MEM_freeN(process.mainb);
/* free octal tree */
- if (G_mb.totelem > 1) {
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
+ if (process.totelem > 1) {
+ free_metaball_octal_node(process.metaball_tree->first);
+ MEM_freeN(process.metaball_tree);
+ process.metaball_tree = NULL;
}
- if (curindex) {
- VERTEX *ptr = mbproc.vertices.ptr;
+ if (process.curindex) {
+ VERTEX *ptr = process.vertices.ptr;
dl = MEM_callocN(sizeof(DispList), "mbaldisp");
BLI_addtail(dispbase, dl);
dl->type = DL_INDEX4;
- dl->nr = mbproc.vertices.count;
- dl->parts = curindex;
+ dl->nr = process.vertices.count;
+ dl->parts = process.curindex;
- dl->index = indices;
- indices = NULL;
+ dl->index = process.indices;
+ process.indices = NULL;
- a = mbproc.vertices.count;
+ a = process.vertices.count;
dl->verts = co = MEM_mallocN(sizeof(float) * 3 * a, "mballverts");
dl->nors = no = MEM_mallocN(sizeof(float) * 3 * a, "mballnors");
- for (a = 0; a < mbproc.vertices.count; ptr++, a++, no += 3, co += 3) {
+ for (a = 0; a < process.vertices.count; ptr++, a++, no += 3, co += 3) {
copy_v3_v3(co, ptr->co);
copy_v3_v3(no, ptr->no);
}
}
- freepolygonize(&mbproc);
+ freepolygonize(&process);
}
/* basic vertex data functions */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index c17830639e4..a0fa3317297 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -36,7 +36,7 @@
* \ingroup bke
*/
-
+#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdarg.h>
@@ -60,6 +60,7 @@
#include "BKE_cloth.h"
#include "BKE_key.h"
#include "BKE_multires.h"
+#include "BKE_DerivedMesh.h"
/* may move these, only for modifier_path_relbase */
#include "BKE_global.h" /* ugh, G.main->name only */
@@ -693,3 +694,65 @@ void modifier_path_init(char *path, int path_maxlen, const char *name)
G.relbase_valid ? "//" : BLI_temporary_dir(),
name);
}
+
+
+/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
+
+struct DerivedMesh *modwrap_applyModifier(
+ ModifierData *md, Object *ob,
+ struct DerivedMesh *dm,
+ ModifierApplyFlag flag)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+
+ if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ DM_ensure_normals(dm);
+ }
+ return mti->applyModifier(md, ob, dm, flag);
+}
+
+struct DerivedMesh *modwrap_applyModifierEM(
+ ModifierData *md, Object *ob,
+ struct BMEditMesh *em,
+ DerivedMesh *dm,
+ ModifierApplyFlag flag)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+
+ if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ DM_ensure_normals(dm);
+ }
+ return mti->applyModifierEM(md, ob, em, dm, flag);
+}
+
+void modwrap_deformVerts(
+ ModifierData *md, Object *ob,
+ DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts,
+ ModifierApplyFlag flag)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+
+ if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ DM_ensure_normals(dm);
+ }
+ mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag);
+}
+
+void modwrap_deformVertsEM(
+ ModifierData *md, Object *ob,
+ struct BMEditMesh *em, DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+
+ if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ DM_ensure_normals(dm);
+ }
+ mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts);
+}
+/* end modifier callback wrappers */
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index a36627bd903..e0a34e35acc 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -162,7 +162,7 @@ void BLI_path_rel(char *file, const char *relfile);
bool BLI_path_is_rel(const char *path);
/* path string comparisons: case-insensitive for Windows, case-sensitive otherwise */
-#ifdef WIN32
+#if defined(WIN32)
# define BLI_path_cmp BLI_strcasecmp
# define BLI_path_ncmp BLI_strncasecmp
#else
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 224d02163cb..4d80080ed86 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -263,9 +263,21 @@
#define STACK_PUSH(stack, val) (void)((stack)[(_##stack##_index)++] = val)
#define STACK_PUSH_RET(stack) ((void)stack, ((stack)[(_##stack##_index)++]))
#define STACK_PUSH_RET_PTR(stack) ((void)stack, &((stack)[(_##stack##_index)++]))
-#define STACK_POP(stack) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL)
-#define STACK_POP_ELSE(stack, r) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : r)
+#define STACK_POP(stack) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL)
+#define STACK_POP_PTR(stack) ((_##stack##_index) ? &((stack)[--(_##stack##_index)]) : NULL)
+#define STACK_POP_ELSE(stack, r) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : r)
#define STACK_FREE(stack) ((void)stack)
+#ifdef __GNUC__
+#define STACK_SWAP(stack_a, stack_b) { \
+ SWAP(typeof(stack_a), stack_a, stack_b); \
+ SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \
+ } (void)0
+#else
+#define STACK_SWAP(stack_a, stack_b) { \
+ SWAP(void *, stack_a, stack_b); \
+ SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \
+ } (void)0
+#endif
/* array helpers */
#define ARRAY_LAST_ITEM(arr_start, arr_dtype, elem_size, tot) \
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index a8fdcd56abb..2da36377e55 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -30,6 +30,7 @@
* \ingroup bli
*/
+#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
@@ -207,6 +208,8 @@ void *BLI_heap_popmin(Heap *heap)
{
void *ptr = heap->tree[0]->ptr;
+ BLI_assert(heap->size == 0);
+
heap->tree[0]->ptr = heap->freenodes;
heap->freenodes = heap->tree[0];
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d44e3fd4948..07ed2f18111 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9605,6 +9605,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
link_list(fd, &user->themes);
link_list(fd, &user->user_keymaps);
link_list(fd, &user->addons);
+ link_list(fd, &user->autoexec_paths);
for (keymap=user->user_keymaps.first; keymap; keymap=keymap->next) {
keymap->modal_items= NULL;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index d8bf1a5e4c4..9b6699f3f21 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -860,6 +860,7 @@ static void write_userdef(WriteData *wd)
wmKeyMapItem *kmi;
wmKeyMapDiffItem *kmdi;
bAddon *bext;
+ bPathCompare *path_cmp;
uiStyle *style;
writestruct(wd, USER, "UserDef", 1, &U);
@@ -888,6 +889,10 @@ static void write_userdef(WriteData *wd)
IDP_WriteProperty(bext->prop, wd);
}
}
+
+ for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) {
+ writestruct(wd, DATA, "bPathCompare", 1, path_cmp);
+ }
for (style= U.uistyles.first; style; style= style->next) {
writestruct(wd, DATA, "uiStyle", 1, style);
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 8d95ab85df8..c92b049eafb 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -290,6 +290,6 @@ extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
* but should not error on valid cases */
#define BM_LOOP_RADIAL_MAX 10000
#define BM_NGON_MAX 100000
-#define BM_OMP_LIMIT 10000 /* setting zero so we can catch bugs in OpenMP/BMesh */
+#define BM_OMP_LIMIT 0 /* 10000 */ /* setting zero so we can catch bugs in OpenMP/BMesh */
#endif /* __BMESH_CLASS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 2608a79d455..313d76721fa 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -498,6 +498,8 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag,
BMIter iter;
int tot = 0;
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
if (htype & BM_VERT) {
for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) {
if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue;
@@ -803,6 +805,8 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
int i;
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
if (hflag & BM_ELEM_SELECT) {
BM_select_history_clear(bm);
}
@@ -872,6 +876,8 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla
BMElem *ele;
int i;
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
if (hflag & BM_ELEM_SELECT) {
BM_select_history_clear(bm);
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 79dacaad2fa..4027d4b2c19 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -628,6 +628,8 @@ void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *fu
*/
int BM_mesh_elem_count(BMesh *bm, const char htype)
{
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
switch (htype) {
case BM_VERT: return bm->totvert;
case BM_EDGE: return bm->totedge;
diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c
index eda252f18f5..9fc1996e51a 100644
--- a/source/blender/bmesh/tools/bmesh_path.c
+++ b/source/blender/bmesh/tools/bmesh_path.c
@@ -144,7 +144,8 @@ LinkNode *BM_mesh_calc_path_vert(
BLI_heap_insert(heap, 0.0f, v_src);
cost[BM_elem_index_get(v_src)] = 0.0f;
- while ((v = BLI_heap_popmin(heap))) {
+ while (!BLI_heap_is_empty(heap)) {
+ v = BLI_heap_popmin(heap);
if (v == v_dst)
break;
@@ -261,7 +262,8 @@ LinkNode *BM_mesh_calc_path_edge(
BLI_heap_insert(heap, 0.0f, e_src);
cost[BM_elem_index_get(e_src)] = 0.0f;
- while ((e = BLI_heap_popmin(heap))) {
+ while (!BLI_heap_is_empty(heap)) {
+ e = BLI_heap_popmin(heap);
if (e == e_dst)
break;
@@ -386,7 +388,8 @@ LinkNode *BM_mesh_calc_path_face(
BLI_heap_insert(heap, 0.0f, f_src);
cost[BM_elem_index_get(f_src)] = 0.0f;
- while ((f = BLI_heap_popmin(heap))) {
+ while (!BLI_heap_is_empty(heap)) {
+ f = BLI_heap_popmin(heap);
if (f == f_dst)
break;
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 097ea477501..f35edb70251 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -76,6 +76,8 @@ struct MeshStatVis;
/* editmesh_utils.c */
+void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em, const bool use_self, const bool use_select,
+ const bool is_topo, float maxdist, int *r_index);
void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const bool use_self, const bool use_select);
void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to);
struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index cb2f3e3286e..86e51b201d9 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -304,7 +304,7 @@ typedef struct uiSearchItems uiSearchItems;
typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr);
typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
-typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
+typedef bool (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items);
typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
@@ -644,7 +644,7 @@ typedef struct AutoComplete AutoComplete;
AutoComplete *autocomplete_begin(const char *startname, size_t maxlen);
void autocomplete_do_name(AutoComplete *autocpl, const char *name);
-void autocomplete_end(AutoComplete *autocpl, char *autoname);
+bool autocomplete_end(AutoComplete *autocpl, char *autoname);
/* Panels
*
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 5a1ba8f31f0..19eb978a01e 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -443,17 +443,24 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int max
static int ui_but_float_precision(uiBut *but, double value)
{
int prec;
+ const double pow10_neg[PRECISION_FLOAT_MAX + 1] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001};
/* first check if prec is 0 and fallback to a simple default */
if ((prec = (int)but->a2) == -1) {
prec = (but->hardmax < 10.001f) ? 3 : 2;
}
+ BLI_assert(prec <= PRECISION_FLOAT_MAX);
+ BLI_assert(pow10_neg[prec] == pow(10, -prec));
+
/* check on the number of decimal places need to display
* the number, this is so 0.00001 is not displayed as 0.00,
* _but_, this is only for small values si 10.0001 will not get
* the same treatment */
- if (value != 0.0 && (value = ABS(value)) < 0.1) {
+ value = ABS(value);
+ if ((value < pow10_neg[prec]) &&
+ (value > (1.0 / PRECISION_FLOAT_MAX_POW)))
+ {
int value_i = (int)((value * PRECISION_FLOAT_MAX_POW) + 0.5);
if (value_i != 0) {
const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
@@ -3086,16 +3093,21 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name)
}
}
-void autocomplete_end(AutoComplete *autocpl, char *autoname)
+bool autocomplete_end(AutoComplete *autocpl, char *autoname)
{
- if (autocpl->truncate[0])
+ bool change = false;
+ if (autocpl->truncate[0]) {
BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen);
+ change = true;
+ }
else {
- if (autoname != autocpl->startname) /* don't copy a string over its self */
+ if (autoname != autocpl->startname) { /* don't copy a string over its self */
BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen);
+ }
}
MEM_freeN(autocpl->truncate);
MEM_freeN(autocpl);
+ return change;
}
static void ui_check_but_and_iconize(uiBut *but, int icon)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index a9378d11cc3..7aee228ddaa 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1828,20 +1828,19 @@ static bool ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directi
static bool ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data)
{
char *str;
- /* TODO, should return false if it cant autocomp. */
- bool changed = true;
+ bool change = true;
str = data->str;
if (data->searchbox)
- ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
+ change = ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
else
- but->autocomplete_func(C, str, but->autofunc_arg);
+ change = but->autocomplete_func(C, str, but->autofunc_arg);
but->pos = strlen(str);
but->selsta = but->selend = but->pos;
- return changed;
+ return change;
}
/* mode for ui_textedit_copypaste() */
@@ -6581,7 +6580,8 @@ static void ui_mouse_motion_towards_reinit(uiPopupBlockHandle *menu, const int x
ui_mouse_motion_towards_init_ex(menu, xy, true);
}
-static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, const int xy[2])
+static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, const int xy[2],
+ const bool use_wiggle_room)
{
float p1[2], p2[2], p3[2], p4[2];
float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]};
@@ -6615,8 +6615,8 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *me
p4[1] = rect_px.ymax + margin;
/* allow for some wiggle room, if the user moves a few pixels away,
- * don't immediately quit */
- {
+ * don't immediately quit (only for top level menus) */
+ if (use_wiggle_room) {
const float cent[2] = {
BLI_rctf_cent_x(&rect_px),
BLI_rctf_cent_y(&rect_px)};
@@ -6789,7 +6789,8 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
return retval;
}
-static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu, int level)
+static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
+ int level, const bool is_parent_inside)
{
ARegion *ar;
uiBlock *block;
@@ -7130,7 +7131,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
}
else {
- ui_mouse_motion_towards_check(block, menu, &event->x);
+ ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false);
/* check mouse moving outside of the menu */
if (inside == 0 && (block->flag & UI_BLOCK_MOVEMOUSE_QUIT)) {
@@ -7233,7 +7234,8 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
return WM_UI_HANDLER_BREAK;
}
-static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu, int level)
+static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
+ int level, const bool is_parent_inside)
{
uiBut *but;
uiHandleButtonData *data;
@@ -7246,8 +7248,21 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
data = (but) ? but->active : NULL;
submenu = (data) ? data->menu : NULL;
- if (submenu)
- retval = ui_handle_menus_recursive(C, event, submenu, level + 1);
+ if (submenu) {
+ bool inside = false;
+
+ if (is_parent_inside == false) {
+ int mx, my;
+ uiBlock *block = menu->region->uiblocks.first;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(menu->region, block, &mx, &my);
+ inside = BLI_rctf_isect_pt(&block->rect, mx, my);
+ }
+
+ retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside);
+ }
/* now handle events for our own menu */
if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
@@ -7275,7 +7290,7 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
}
}
else {
- retval = ui_handle_menu_event(C, event, menu, level);
+ retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside);
}
}
@@ -7371,7 +7386,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
/* handle events for menus and their buttons recursively,
* this will handle events from the top to the bottom menu */
if (data->menu)
- retval = ui_handle_menus_recursive(C, event, data->menu, 0);
+ retval = ui_handle_menus_recursive(C, event, data->menu, 0, false);
/* handle events for the activated button */
if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
@@ -7417,7 +7432,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
retval = WM_UI_HANDLER_CONTINUE;
}
- ui_handle_menus_recursive(C, event, menu, 0);
+ ui_handle_menus_recursive(C, event, menu, 0, false);
/* free if done, does not free handle itself */
if (menu->menuretval) {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 9de608f2730..a6076b8df78 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -471,7 +471,7 @@ ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBu
bool ui_searchbox_inside(struct ARegion *ar, int x, int y);
int ui_searchbox_find_index(struct ARegion *ar, const char *name);
void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, const bool reset);
-void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
+bool ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event);
bool ui_searchbox_apply(uiBut *but, struct ARegion *ar);
void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index b6575f4eca0..ef839f1d143 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -525,7 +525,7 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
name = (!uiname || uiname[0]) ? item->name : "";
icon = item->icon;
value = item->value;
- itemw = ui_text_icon_width(block->curlayout, name, icon, 0);
+ itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0);
if (icon && name[0] && !icon_only)
but = uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index b764c70b111..1ff46004bdf 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1039,18 +1039,20 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset)
ED_region_tag_redraw(ar);
}
-void ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
+bool ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
{
uiSearchboxData *data = ar->regiondata;
+ bool changed = false;
if (str[0]) {
data->items.autocpl = autocomplete_begin(str, ui_get_but_string_max_length(but));
but->search_func(C, but->search_arg, but->editstr, &data->items);
- autocomplete_end(data->items.autocpl, str);
+ changed = autocomplete_end(data->items.autocpl, str);
data->items.autocpl = NULL;
}
+ return changed;
}
static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 00eabad729e..d8efb972ce9 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2286,8 +2286,7 @@ static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol)
}
/* ************ button callbacks, draw ***************** */
-
-static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign, bool emboss)
{
uiWidgetBase wtb;
const float rad = 0.5f * BLI_rcti_size_y(rect);
@@ -2298,9 +2297,10 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round
widget_init(&wtb);
- /* fully rounded */
- round_box_edges(&wtb, roundboxalign, rect, rad);
-
+ if (!emboss) {
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+ }
+
/* decoration */
if (!(state & UI_TEXTINPUT)) {
widget_num_tria(&wtb.tria1, rect, 0.6f, 'l');
@@ -2314,6 +2314,19 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round
rect->xmax -= textofs;
}
+static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+ widget_numbut_draw(wcol, rect, state, roundboxalign, false);
+}
+
+/*
+ * Draw number buttons still with triangles when field is not embossed
+*/
+static void widget_numbut_embossn(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+ widget_numbut_draw(wcol, rect, state, roundboxalign, true);
+}
+
int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
{
float dist, vec[4][2];
@@ -2671,7 +2684,7 @@ static void widget_normal(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUS
ui_draw_but_NORMAL(but, wcol, rect);
}
-static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
+static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
uiWidgetBase wtb;
@@ -2685,6 +2698,11 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
+ else if (but->type == NUM) {
+ /* Draw number buttons still with left/right
+ * triangles when field is not embossed */
+ widget_numbut_embossn(but, wcol, rect, state, roundboxalign);
+ }
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index fa857edb6fc..963b9cf134b 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -507,17 +507,20 @@ bool EDBM_index_arrays_check(BMEditMesh *em)
BMVert *EDBM_vert_at_index(BMEditMesh *em, int index)
{
- return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL;
+ BLI_assert((index >= 0) && (index < em->bm->totvert));
+ return em->vert_index[index];
}
BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index)
{
- return em->edge_index && index < em->bm->totedge ? em->edge_index[index] : NULL;
+ BLI_assert((index >= 0) && (index < em->bm->totedge));
+ return em->edge_index[index];
}
BMFace *EDBM_face_at_index(BMEditMesh *em, int index)
{
- return (em->face_index && index < em->bm->totface && index >= 0) ? em->face_index[index] : NULL;
+ BLI_assert((index >= 0) && (index < em->bm->totface));
+ return em->face_index[index];
}
void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode)
@@ -1144,46 +1147,58 @@ static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index)
* preference */
#define BM_SEARCH_MAXDIST_MIRR 0.00002f
#define BM_CD_LAYER_ID "__mirror_index"
-void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select)
+/**
+ * \param em Editmesh.
+ * \param use_self Allow a vertex to point to its self (middle verts).
+ * \param use_select Restrict to selected verts.
+ * \param is_topo Use topology mirror.
+ * \param maxdist Distance for close point test.
+ * \param r_index Optional array to write into, as an alternative to a customdata layer (length of total verts).
+ */
+void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const bool use_select,
+ /* extra args */
+ const bool is_topo, float maxdist, int *r_index)
{
Mesh *me = (Mesh *)em->ob->data;
BMesh *bm = em->bm;
BMIter iter;
BMVert *v;
- bool topo = false;
int cd_vmirr_offset;
+ int i;
/* one or the other is used depending if topo is enabled */
struct BMBVHTree *tree = NULL;
MirrTopoStore_t mesh_topo_store = {NULL, -1, -1, -1};
- if (me && (me->editflag & ME_EDIT_MIRROR_TOPO)) {
- topo = 1;
- }
-
EDBM_index_arrays_ensure(em, BM_VERT);
- em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID);
- if (em->mirror_cdlayer == -1) {
- BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID);
- em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID);
- }
+ if (r_index == NULL) {
+ const char *layer_id = BM_CD_LAYER_ID;
+ em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id);
+ if (em->mirror_cdlayer == -1) {
+ BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, layer_id);
+ em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id);
+ }
- cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT,
- em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT));
+ cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT,
+ em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT));
- bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY;
+ bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY;
+ }
BM_mesh_elem_index_ensure(bm, BM_VERT);
- if (topo) {
+ if (is_topo) {
ED_mesh_mirrtopo_init(me, -1, &mesh_topo_store, true);
}
else {
tree = BKE_bmbvh_new(em, 0, NULL, false);
}
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+#define VERT_INTPTR(_v, _i) r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset);
+
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ BLI_assert(BM_elem_index_get(v) == i);
/* temporary for testing, check for selection */
if (use_select && !BM_elem_flag_test(v, BM_ELEM_SELECT)) {
@@ -1191,20 +1206,21 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo
}
else {
BMVert *v_mirr;
- int *idx = BM_ELEM_CD_GET_VOID_P(v, cd_vmirr_offset);
+ int *idx = VERT_INTPTR(v, i);
- if (topo) {
- v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, BM_elem_index_get(v));
+ if (is_topo) {
+ v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i);
}
else {
float co[3] = {-v->co[0], v->co[1], v->co[2]};
- v_mirr = BKE_bmbvh_find_vert_closest(tree, co, BM_SEARCH_MAXDIST_MIRR);
+ v_mirr = BKE_bmbvh_find_vert_closest(tree, co, maxdist);
}
if (v_mirr && (use_self || (v_mirr != v))) {
- *idx = BM_elem_index_get(v_mirr);
- idx = BM_ELEM_CD_GET_VOID_P(v_mirr, cd_vmirr_offset);
- *idx = BM_elem_index_get(v);
+ const int i_mirr = BM_elem_index_get(v_mirr);
+ *idx = i_mirr;
+ idx = VERT_INTPTR(v_mirr, i_mirr);
+ *idx = i;
}
else {
*idx = -1;
@@ -1213,8 +1229,9 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo
}
+#undef VERT_INTPTR
- if (topo) {
+ if (is_topo) {
ED_mesh_mirrtopo_free(&mesh_topo_store);
}
else {
@@ -1222,6 +1239,18 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo
}
}
+void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select)
+{
+ Mesh *me = (Mesh *)em->ob->data;
+ bool is_topo;
+
+ is_topo = (me && (me->editflag & ME_EDIT_MIRROR_TOPO));
+
+ EDBM_verts_mirror_cache_begin_ex(em, use_self, use_select,
+ /* extra args */
+ is_topo, BM_SEARCH_MAXDIST_MIRR, NULL);
+}
+
BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v)
{
int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 74f1515fe74..8da953c4f84 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -2905,9 +2905,9 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO;
/* properties */
- prop = RNA_def_boolean(ot->srna, "use_all_groups", 0, "All Groups", "Remove from all Groups");
+ prop = RNA_def_boolean(ot->srna, "use_all_groups", 0, "All Groups", "Remove from all groups");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "use_all_verts", 0, "All verts", "Clear Active Group");
+ prop = RNA_def_boolean(ot->srna, "use_all_verts", 0, "All Verts", "Clear the active group");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 20edd3d32e7..527715cdbd3 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -220,7 +220,7 @@ static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
return OPERATOR_CANCELLED;
}
-static int screenshot_check(bContext *UNUSED(C), wmOperator *op)
+static bool screenshot_check(bContext *UNUSED(C), wmOperator *op)
{
ScreenshotData *scd = op->customdata;
return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 1ff7df3b041..181b32d58fc 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2145,7 +2145,7 @@ struct WPaintData {
};
/* ensure we have data on wpaint start, add if needed */
-static int wpaint_ensure_data(bContext *C, wmOperator *op)
+static bool wpaint_ensure_data(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
@@ -3390,6 +3390,10 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
vert_cache = gesture->userdata;
}
else {
+ if (wpaint_ensure_data(C, op) == FALSE) {
+ return OPERATOR_CANCELLED;
+ }
+
data.is_init = true;
vert_cache = MEM_mallocN(sizeof(DMGradient_vertStore) * me->totvert, __func__);
}
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 0cb0a3d6e5c..a2189f6237c 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -391,7 +391,7 @@ static const char *snd_ext_sound[] = {
NULL
};
-static int sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
+static bool sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
{
AUD_Container container = RNA_enum_get(op->ptr, "container");
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt
index b20301cfc3b..9e045a39a0c 100644
--- a/source/blender/editors/space_buttons/CMakeLists.txt
+++ b/source/blender/editors/space_buttons/CMakeLists.txt
@@ -35,7 +35,6 @@ set(INC_SYS
set(SRC
buttons_context.c
- buttons_header.c
buttons_ops.c
buttons_texture.c
space_buttons.c
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
deleted file mode 100644
index f9742121e99..00000000000
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2008 Blender Foundation.
- * All rights reserved.
- *
- *
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/space_buttons/buttons_header.c
- * \ingroup spbuttons
- */
-
-
-#include <string.h>
-#include <stdio.h>
-
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-
-#include "BLF_translation.h"
-
-#include "BKE_context.h"
-#include "BKE_modifier.h"
-#include "BKE_paint.h"
-#include "BKE_scene.h"
-
-#include "ED_buttons.h"
-#include "ED_screen.h"
-#include "ED_types.h"
-
-#include "DNA_brush_types.h"
-#include "DNA_object_force.h"
-#include "DNA_object_types.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-#include "UI_view2d.h"
-
-#include "buttons_intern.h"
-
-
-#define B_CONTEXT_SWITCH 101
-
-static void set_texture_context(const bContext *C, SpaceButs *sbuts)
-{
- Scene *scene = CTX_data_scene(C);
-
- if (BKE_scene_use_new_shading_nodes(scene)) {
- return; /* No texture context in new shading mode */
- }
-
- if ((sbuts->mainb == BCONTEXT_WORLD) && ED_texture_context_check_world(C)) {
- sbuts->texture_context = SB_TEXC_WORLD;
- }
- else if ((sbuts->mainb == BCONTEXT_MATERIAL) && ED_texture_context_check_material(C)) {
- sbuts->texture_context = SB_TEXC_MATERIAL;
- }
- else if ((sbuts->mainb == BCONTEXT_DATA) && ED_texture_context_check_lamp(C)) {
- sbuts->texture_context = SB_TEXC_LAMP;
- }
- else if ((sbuts->mainb == BCONTEXT_PARTICLE) && ED_texture_context_check_particles(C)) {
- sbuts->texture_context = SB_TEXC_PARTICLES;
- }
- else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && ED_texture_context_check_others(C)) {
- sbuts->texture_context = SB_TEXC_OTHER;
- }
- /* Second pass: sbuts->mainbuser still contains the previous button context.
- * Useful e.g. when we switch to material, no material present, add a material, switch to texture.
- * See #35741. */
- else if ((sbuts->mainbuser == BCONTEXT_WORLD) && ED_texture_context_check_world(C)) {
- sbuts->texture_context = SB_TEXC_WORLD;
- }
- else if ((sbuts->mainbuser == BCONTEXT_MATERIAL) && ED_texture_context_check_material(C)) {
- sbuts->texture_context = SB_TEXC_MATERIAL;
- }
- else if ((sbuts->mainbuser == BCONTEXT_DATA) && ED_texture_context_check_lamp(C)) {
- sbuts->texture_context = SB_TEXC_LAMP;
- }
- else if ((sbuts->mainbuser == BCONTEXT_PARTICLE) && ED_texture_context_check_particles(C)) {
- sbuts->texture_context = SB_TEXC_PARTICLES;
- }
- else if ((ELEM(sbuts->mainbuser, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && ED_texture_context_check_others(C)) {
- sbuts->texture_context = SB_TEXC_OTHER;
- }
- /* Else, just be sure that current context is valid! */
- else {
- buttons_check_texture_context(C, sbuts);
- }
-}
-
-static void do_buttons_buttons(bContext *C, void *UNUSED(arg), int event)
-{
- SpaceButs *sbuts = CTX_wm_space_buts(C);
-
- if (!sbuts) /* editor type switch */
- return;
-
- switch (event) {
- case B_CONTEXT_SWITCH:
- ED_area_tag_redraw(CTX_wm_area(C));
-
- set_texture_context(C, sbuts);
-
- sbuts->preview = 1;
- break;
- }
-
- sbuts->mainbuser = sbuts->mainb;
-}
-
-#define BUT_UNIT_X (UI_UNIT_X + 2 * U.pixelsize)
-
-void buttons_header_buttons(const bContext *C, ARegion *ar)
-{
- SpaceButs *sbuts = CTX_wm_space_buts(C);
- uiBlock *block;
- uiBut *but;
- int headery = ED_area_headersize();
- int xco, yco = 0.5f * (headery - UI_UNIT_Y);
-
- buttons_context_compute(C, sbuts);
-
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockSetHandleFunc(block, do_buttons_buttons, NULL);
-
- xco = ED_area_header_switchbutton(C, block, yco);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- xco -= UI_UNIT_X;
-
- /* Default panels */
-
- uiBlockBeginAlign(block);
-
-#define BUTTON_HEADER_CTX(_ctx, _icon, _tip) \
- if (sbuts->pathflag & (1 << _ctx)) { \
- but = uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, _icon, xco += BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, \
- &(sbuts->mainb), 0.0, (float)_ctx, 0, 0, TIP_(_tip)); \
- uiButClearFlag(but, UI_BUT_UNDO); \
- } (void)0
-
- BUTTON_HEADER_CTX(BCONTEXT_RENDER, ICON_SCENE, N_("Render"));
- BUTTON_HEADER_CTX(BCONTEXT_RENDER_LAYER, ICON_RENDERLAYERS, N_("Render Layers"));
- BUTTON_HEADER_CTX(BCONTEXT_SCENE, ICON_SCENE_DATA, N_("Scene"));
- BUTTON_HEADER_CTX(BCONTEXT_WORLD, ICON_WORLD, N_("World"));
- BUTTON_HEADER_CTX(BCONTEXT_OBJECT, ICON_OBJECT_DATA, N_("Object"));
- BUTTON_HEADER_CTX(BCONTEXT_CONSTRAINT, ICON_CONSTRAINT, N_("Object Constraints"));
- BUTTON_HEADER_CTX(BCONTEXT_MODIFIER, ICON_MODIFIER, N_("Object Modifiers"));
- BUTTON_HEADER_CTX(BCONTEXT_DATA, sbuts->dataicon, N_("Object Data"));
- BUTTON_HEADER_CTX(BCONTEXT_BONE, ICON_BONE_DATA, N_("Bone"));
- BUTTON_HEADER_CTX(BCONTEXT_BONE_CONSTRAINT, ICON_CONSTRAINT_BONE, N_("Bone Constraints"));
- BUTTON_HEADER_CTX(BCONTEXT_MATERIAL, ICON_MATERIAL, N_("Material"));
- BUTTON_HEADER_CTX(BCONTEXT_TEXTURE, ICON_TEXTURE, N_("Textures"));
- BUTTON_HEADER_CTX(BCONTEXT_PARTICLE, ICON_PARTICLES, N_("Particles"));
- BUTTON_HEADER_CTX(BCONTEXT_PHYSICS, ICON_PHYSICS, N_("Physics"));
-
-#undef BUTTON_HEADER_CTX
-
- xco += BUT_UNIT_X;
-
- uiBlockEndAlign(block);
-
- /* always as last */
- UI_view2d_totRect_set(&ar->v2d, xco + (UI_UNIT_X / 2), BLI_rctf_size_y(&ar->v2d.tot));
-
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
-}
-
-
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index 55c9bf0dffd..f294729ae97 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -97,9 +97,6 @@ typedef struct ButsContextTexture {
/* internal exports only */
-/* buttons_header.c */
-void buttons_header_buttons(const struct bContext *C, struct ARegion *ar);
-
/* buttons_context.c */
void buttons_context_compute(const struct bContext *C, struct SpaceButs *sbuts);
int buttons_context(const struct bContext *C, const char *member, struct bContextDataResult *result);
@@ -111,7 +108,6 @@ extern const char *buttons_context_dir[]; /* doc access */
/* buttons_texture.c */
void buttons_texture_context_compute(const struct bContext *C, struct SpaceButs *sbuts);
-void buttons_check_texture_context(const struct bContext *C, struct SpaceButs *sbuts);
/* buttons_ops.c */
void BUTTONS_OT_file_browse(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 0b1f244a1b5..51e740e539f 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -135,8 +135,7 @@ bool ED_texture_context_check_others(const bContext *C)
return false;
}
-/* Only change texture context if current one is invalid! */
-void buttons_check_texture_context(const bContext *C, SpaceButs *sbuts)
+static void set_texture_context(const bContext *C, SpaceButs *sbuts)
{
Scene *scene = CTX_data_scene(C);
@@ -151,11 +150,27 @@ void buttons_check_texture_context(const bContext *C, SpaceButs *sbuts)
bool valid_particles = ED_texture_context_check_particles(C);
bool valid_others = ED_texture_context_check_others(C);
- if (((sbuts->texture_context == SB_TEXC_WORLD) && !valid_world) ||
- ((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) ||
- ((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) ||
- ((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) ||
- ((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others))
+ if ((sbuts->mainb == BCONTEXT_WORLD) && valid_world) {
+ sbuts->texture_context = SB_TEXC_WORLD;
+ }
+ else if ((sbuts->mainb == BCONTEXT_MATERIAL) && valid_material) {
+ sbuts->texture_context = SB_TEXC_MATERIAL;
+ }
+ else if ((sbuts->mainb == BCONTEXT_DATA) && valid_lamp) {
+ sbuts->texture_context = SB_TEXC_LAMP;
+ }
+ else if ((sbuts->mainb == BCONTEXT_PARTICLE) && valid_particles) {
+ sbuts->texture_context = SB_TEXC_PARTICLES;
+ }
+ else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && valid_others) {
+ sbuts->texture_context = SB_TEXC_OTHER;
+ }
+ /* Else, just be sure that current context is valid! */
+ else if (((sbuts->texture_context == SB_TEXC_WORLD) && !valid_world) ||
+ ((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) ||
+ ((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) ||
+ ((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) ||
+ ((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others))
{
if (valid_others) {
sbuts->texture_context = SB_TEXC_OTHER;
@@ -368,7 +383,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
Scene *scene = CTX_data_scene(C);
ID *pinid = sbuts->pinid;
- buttons_check_texture_context(C, sbuts);
+ set_texture_context(C, sbuts);
if (!(BKE_scene_use_new_shading_nodes(scene) || (sbuts->texture_context == SB_TEXC_OTHER))) {
if (ct) {
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 02b06e08eed..e6c6df416bf 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -87,7 +87,7 @@ static SpaceLink *buttons_new(const bContext *UNUSED(C))
BLI_addtail(&sbuts->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
return (SpaceLink *)sbuts;
}
@@ -200,22 +200,17 @@ static void buttons_keymap(struct wmKeyConfig *keyconf)
/* add handlers, stuff you only do once or on area/region changes */
static void buttons_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
{
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+ ED_region_header_init(ar);
}
static void buttons_header_area_draw(const bContext *C, ARegion *ar)
{
- /* clear */
- UI_ThemeClearColor(ED_screen_area_active(C) ? TH_HEADER : TH_HEADERDESEL);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(&ar->v2d);
-
- buttons_header_buttons(C, ar);
+ SpaceButs *sbuts = CTX_wm_space_buts(C);
+
+ /* Needed for RNA to get the good values! */
+ buttons_context_compute(C, sbuts);
- /* restore view matrix? */
- UI_view2d_view_restore(C);
+ ED_region_header(C, ar);
}
/* draw a certain button set only if properties area is currently
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 60420649093..986b71abc8a 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -807,7 +807,7 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
- if (ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */
+ if (ELEM4(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */
return TRUE;
return FALSE;
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index e5c6a839380..240106d37d5 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -105,8 +105,8 @@ float file_string_width(const char *str);
float file_font_pointsize(void);
void file_change_dir(bContext *C, int checkdir);
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file);
-void autocomplete_directory(struct bContext *C, char *str, void *arg_v);
-void autocomplete_file(struct bContext *C, char *str, void *arg_v);
+bool autocomplete_directory(struct bContext *C, char *str, void *arg_v);
+bool autocomplete_file(struct bContext *C, char *str, void *arg_v);
/* file_panels.c */
void file_panels_register(struct ARegionType *art);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 25d865d857b..a31af851575 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -609,6 +609,7 @@ void file_change_dir(bContext *C, int checkdir)
folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
+ file_draw_check_cb(C, NULL, NULL);
}
}
@@ -637,9 +638,10 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche
return match;
}
-void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
+bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ bool change = false;
/* search if str matches the beginning of name */
if (str[0] && sfile->files) {
@@ -674,20 +676,25 @@ void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
}
closedir(dir);
- autocomplete_end(autocpl, str);
- if (BLI_exists(str)) {
- BLI_add_slash(str);
- }
- else {
- BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir));
+ change = autocomplete_end(autocpl, str);
+ if (change) {
+ if (BLI_exists(str)) {
+ BLI_add_slash(str);
+ }
+ else {
+ BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir));
+ }
}
}
}
+
+ return change;
}
-void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
+bool autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ bool change = false;
/* search if str matches the beginning of name */
if (str[0] && sfile->files) {
@@ -701,8 +708,9 @@ void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
autocomplete_do_name(autocpl, file->relname);
}
}
- autocomplete_end(autocpl, str);
+ change = autocomplete_end(autocpl, str);
}
+ return change;
}
void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile)
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 8272222e4c2..0a2bd2aad81 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1441,7 +1441,7 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
}
-static int image_save_as_check(bContext *UNUSED(C), wmOperator *op)
+static bool image_save_as_check(bContext *UNUSED(C), wmOperator *op)
{
ImageFormatData *imf = op->customdata;
return WM_operator_filesel_ensure_ext_imtype(op, imf);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 164382c300d..159cc74af56 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -425,8 +425,7 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
if (items == 0) {
BKE_report(op->reports, RPT_ERROR,
- "No active track(s) to add strip to. "
- "Select an existing track or add one before trying again");
+ "No active track(s) to add strip to, select an existing track or add one before trying again");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 0d875acb040..2fa901a2f28 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -773,8 +773,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
#define B_VGRP_PNL_COPY 1
#define B_VGRP_PNL_NORMALIZE 2
-#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
-#define B_VGRP_PNL_COPY_SINGLE 16384 /* or greater */
+#define B_VGRP_PNL_TOGGLE_USE_ALL 4
+#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
+#define B_VGRP_PNL_DELETE_SINGLE 4096 /* or greater */
+#define B_VGRP_PNL_COPY_SINGLE 8192 /* or greater */
+#define B_VGRP_PNL_ACTIVE 16384 /* or greater */
+
static MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
{
@@ -904,6 +908,18 @@ static void vgroup_adjust_active(Object *ob, int def_nr)
}
}
+static void vgroup_remove_weight(Object *ob, const int def_nr)
+{
+ MDeformVert *dvert_act;
+ MDeformWeight *dw;
+
+ dvert_act = ED_mesh_active_dvert_get_only(ob);
+
+ dw = defvert_find_index(dvert_act, def_nr);
+ defvert_remove_group(dvert_act, dw);
+
+}
+
static void vgroup_copy_active_to_sel(Object *ob)
{
Mesh *me = ob->data;
@@ -1064,9 +1080,15 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
else if (event == B_VGRP_PNL_COPY) {
vgroup_copy_active_to_sel(ob);
}
+ else if (event >= B_VGRP_PNL_ACTIVE) {
+ ob->actdef = event - B_VGRP_PNL_ACTIVE + 1;
+ }
else if (event >= B_VGRP_PNL_COPY_SINGLE) {
vgroup_copy_active_to_sel_single(ob, event - B_VGRP_PNL_COPY_SINGLE);
}
+ else if (event >= B_VGRP_PNL_DELETE_SINGLE) {
+ vgroup_remove_weight(ob, event - B_VGRP_PNL_DELETE_SINGLE);
+ }
else if (event >= B_VGRP_PNL_EDIT_SINGLE) {
vgroup_adjust_active(ob, event - B_VGRP_PNL_EDIT_SINGLE);
}
@@ -1111,6 +1133,9 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
if (dv && dv->totweight) {
uiLayout *col;
+ uiLayout *row;
+ uiLayout *box;
+ uiBut *but;
bDeformGroup *dg;
unsigned int i;
int subset_count, vgroup_tot;
@@ -1119,22 +1144,50 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
int yco = 0;
uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL);
+ box = uiLayoutBox(pa->layout);
- col = uiLayoutColumn(pa->layout, FALSE);
- block = uiLayoutAbsoluteBlock(col);
-
- uiBlockBeginAlign(block);
+ col = uiLayoutColumn(box, true);
vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
if (vgroup_validmap[i]) {
MDeformWeight *dw = defvert_find_index(dv, i);
if (dw) {
- uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, dg->name, 0, yco, 180, 20,
+ int x, xco = 0;
+ row = uiLayoutRow(col, true);
+ (void)row;
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ but = uiDefBut(block, BUT, B_VGRP_PNL_ACTIVE + i, dg->name,
+ xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y,
+ NULL, 0.0, 1.0, 1, 3, "");
+ uiButSetFlag(but, UI_TEXT_LEFT);
+
+ if (ob->actdef != i + 1) {
+ uiButSetFlag(but, UI_BUT_INACTIVE);
+ }
+ xco += x;
+
+ //uiBlockSetEmboss(block, UI_EMBOSS);
+
+ but = uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, "",
+ xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y,
&dw->weight, 0.0, 1.0, 1, 3, "");
- uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, "C", 180, yco, 20, 20,
- NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts"));
- yco -= 20;
+ uiButSetFlag(but, UI_TEXT_LEFT);
+ xco += x;
+
+ uiDefIconBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, ICON_PASTEDOWN,
+ xco, yco, (x = UI_UNIT_X), UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts"));
+ xco += x;
+
+ uiDefIconBut(block, BUT, B_VGRP_PNL_DELETE_SINGLE + i, ICON_X,
+ xco, yco, (x = UI_UNIT_X), UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Delete this weight from the vertex"));
+ xco += x;
+
+ yco -= UI_UNIT_Y;
+ (void)xco;
}
}
}
@@ -1142,13 +1195,16 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
yco -= 2;
- uiBlockEndAlign(block);
- uiBlockBeginAlign(block);
- uiDefBut(block, BUT, B_VGRP_PNL_NORMALIZE, IFACE_("Normalize"), 0, yco, 100, 20,
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ col = uiLayoutColumn(pa->layout, true);
+ row = uiLayoutRow(col, true);
+
+ uiDefBut(block, BUT, B_VGRP_PNL_NORMALIZE, IFACE_("Normalize"),
+ 0, yco, UI_UNIT_X * 5, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Normalize active vertex weights"));
- uiDefBut(block, BUT, B_VGRP_PNL_COPY, IFACE_("Copy"), 100, yco, 100, 20,
+ uiDefBut(block, BUT, B_VGRP_PNL_COPY, IFACE_("Copy"),
+ UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Copy active vertex to other selected verts"));
- uiBlockEndAlign(block);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 9e310c84bd0..180686b4b82 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -237,7 +237,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo
foreachScreenFace_userData *data = userData;
BMFace *efa = EDBM_face_at_index(data->vc.em, index);
- if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
float screen_co[2];
if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) {
data->func(data->userData, efa, screen_co, index);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index bba151f1a5e..c119fe24210 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1166,6 +1166,26 @@ static bool selectbuffer_has_bones(const unsigned int *buffer, const unsigned in
return false;
}
+/* utility function for mixed_bones_object_selectbuffer */
+static short selectbuffer_ret_hits_15(unsigned int *UNUSED(buffer), const short hits15)
+{
+ return hits15;
+}
+
+static short selectbuffer_ret_hits_9(unsigned int *buffer, const short hits15, const short hits9)
+{
+ const int offs = 4 * hits15;
+ memcpy(buffer, buffer + offs, 4 * offs);
+ return hits9;
+}
+
+static short selectbuffer_ret_hits_5(unsigned int *buffer, const short hits15, const short hits9, const short hits5)
+{
+ const int offs = 4 * hits15 + 4 * hits9;
+ memcpy(buffer, buffer + offs, 4 * offs);
+ return hits5;
+}
+
/* we want a select buffer with bones, if there are... */
/* so check three selection levels and compare */
static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buffer, const int mval[2])
@@ -1177,48 +1197,39 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff
BLI_rcti_init(&rect, mval[0] - 14, mval[0] + 14, mval[1] - 14, mval[1] + 14);
hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
- if (hits15 > 0) {
+ if (hits15 == 1) {
+ return selectbuffer_ret_hits_15(buffer, hits15);
+ }
+ else if (hits15 > 0) {
has_bones15 = selectbuffer_has_bones(buffer, hits15);
offs = 4 * hits15;
BLI_rcti_init(&rect, mval[0] - 9, mval[0] + 9, mval[1] - 9, mval[1] + 9);
hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
- if (hits9 > 0) {
+ if (hits9 == 1) {
+ return selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ }
+ else if (hits9 > 0) {
has_bones9 = selectbuffer_has_bones(buffer + offs, hits9);
offs += 4 * hits9;
BLI_rcti_init(&rect, mval[0] - 5, mval[0] + 5, mval[1] - 5, mval[1] + 5);
hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
- if (hits5 > 0) {
+ if (hits5 == 1) {
+ return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ }
+ else if (hits5 > 0) {
has_bones5 = selectbuffer_has_bones(buffer + offs, hits5);
}
}
+
+ if (has_bones5) return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ else if (has_bones9) return selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ else if (has_bones15) return selectbuffer_ret_hits_15(buffer, hits15);
- if (has_bones5) {
- offs = 4 * hits15 + 4 * hits9;
- memcpy(buffer, buffer + offs, 4 * offs);
- return hits5;
- }
- if (has_bones9) {
- offs = 4 * hits15;
- memcpy(buffer, buffer + offs, 4 * offs);
- return hits9;
- }
- if (has_bones15) {
- return hits15;
- }
-
- if (hits5 > 0) {
- offs = 4 * hits15 + 4 * hits9;
- memcpy(buffer, buffer + offs, 4 * offs);
- return hits5;
- }
- if (hits9 > 0) {
- offs = 4 * hits15;
- memcpy(buffer, buffer + offs, 4 * offs);
- return hits9;
- }
- return hits15;
+ if (hits5 > 0) return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ else if (hits9 > 0) return selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ else return selectbuffer_ret_hits_15(buffer, hits15);
}
return 0;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index d8f763c6a54..ac5727a116c 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -196,7 +196,7 @@ static void sort_trans_data(TransInfo *t)
/* distance calculated from not-selected vertex to nearest selected vertex
* warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */
-static void set_prop_dist(TransInfo *t, short with_dist)
+static void set_prop_dist(TransInfo *t, const bool with_dist)
{
TransData *tob;
int a;
@@ -216,12 +216,9 @@ static void set_prop_dist(TransInfo *t, short with_dist)
if (td->flag & TD_SELECTED) {
sub_v3_v3v3(vec, tob->center, td->center);
mul_m3_v3(tob->mtx, vec);
- dist = normalize_v3(vec);
- if (tob->rdist == -1.0f) {
- tob->rdist = dist;
- }
- else if (dist < tob->rdist) {
- tob->rdist = dist;
+ dist = len_squared_v3(vec);
+ if ((tob->rdist == -1.0f) || (dist < (tob->rdist * tob->rdist))) {
+ tob->rdist = sqrtf(dist);
}
}
else {
@@ -1778,90 +1775,125 @@ void flushTransParticles(TransInfo *t)
/* ********************* mesh ****************** */
-/* I did this wrong, it should be a breadth-first search
- * but instead it's a depth-first search, fudged
- * to report shortest distances. I have no idea how fast
- * or slow this is. */
-static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[3][3], float *dists)
+static bool bmesh_test_dist_add(BMVert *v, BMVert *v_other,
+ float *dists, const float *dists_prev,
+ float mtx[3][3])
{
- BMVert **queue = NULL;
- float *dqueue = NULL;
- int *tots = MEM_callocN(sizeof(int) * em->bm->totvert, "tots editmesh_set_connectivity_distance");
- BLI_array_declare(queue);
- BLI_array_declare(dqueue);
- SmallHash svisit, *visit = &svisit;
- BMVert *v;
- BMIter viter;
- int i, start;
-
- fill_vn_fl(dists, em->bm->totvert, FLT_MAX);
+ if ((BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) &&
+ (BM_elem_flag_test(v_other, BM_ELEM_HIDDEN) == 0))
+ {
+ const int i = BM_elem_index_get(v);
+ const int i_other = BM_elem_index_get(v_other);
+ float vec[3];
+ float dist_other;
+ sub_v3_v3v3(vec, v->co, v_other->co);
+ mul_m3_v3(mtx, vec);
+
+ dist_other = dists_prev[i] + len_v3(vec);
+ if (dist_other < dists[i_other]) {
+ dists[i_other] = dist_other;
+ return true;
+ }
+ }
- BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+ return false;
+}
- BLI_smallhash_init(visit);
+static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists)
+{
+ /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
+ float *dists_prev = MEM_mallocN(bm->totvert * sizeof(float), __func__);
- BM_ITER_MESH (v, &viter, em->bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN))
- continue;
-
-
- BLI_smallhash_insert(visit, (uintptr_t)v, NULL);
- BLI_array_append(queue, v);
- BLI_array_append(dqueue, 0.0f);
- dists[BM_elem_index_get(v)] = 0.0f;
+ BMVert **queue = MEM_mallocN(bm->totvert * sizeof(BMVert *), __func__);
+ STACK_DECLARE(queue);
+
+ /* any BM_ELEM_TAG'd vertex is in 'queue_next', so we don't add in twice */
+ BMVert **queue_next = MEM_mallocN(bm->totvert * sizeof(BMVert *), __func__);
+ STACK_DECLARE(queue_next);
+
+ STACK_INIT(queue);
+ STACK_INIT(queue_next);
+
+ {
+ BMIter viter;
+ BMVert *v;
+ int i;
+
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ BM_elem_index_set(v, i); /* set_inline */
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+ dists[i] = FLT_MAX;
+ }
+ else {
+ STACK_PUSH(queue, v);
+
+ dists[i] = 0.0f;
+ }
+ }
}
-
- start = 0;
- while (start < BLI_array_count(queue)) {
- BMIter eiter;
- BMEdge *e;
- BMVert *v3, *v2;
- float d, vec[3];
-
- v2 = queue[start];
- d = dqueue[start];
-
- BM_ITER_ELEM (e, &eiter, v2, BM_EDGES_OF_VERT) {
- float d2;
- v3 = BM_edge_other_vert(e, v2);
-
- if (BM_elem_flag_test(v3, BM_ELEM_SELECT) || BM_elem_flag_test(v3, BM_ELEM_HIDDEN))
- continue;
-
- sub_v3_v3v3(vec, v2->co, v3->co);
- mul_m3_v3(mtx, vec);
-
- d2 = d + len_v3(vec);
-
- if (dists[BM_elem_index_get(v3)] != FLT_MAX)
- dists[BM_elem_index_get(v3)] = min_ff(d2, dists[BM_elem_index_get(v3)]);
- else
- dists[BM_elem_index_get(v3)] = d2;
-
- tots[BM_elem_index_get(v3)] = 1;
- if (BLI_smallhash_haskey(visit, (uintptr_t)v3))
- continue;
-
- BLI_smallhash_insert(visit, (uintptr_t)v3, NULL);
+ do {
+ BMVert *v;
+ unsigned int i;
+
+ memcpy(dists_prev, dists, sizeof(float) * bm->totvert);
+
+ while ((v = STACK_POP(queue))) {
+ BMIter iter;
+ BMEdge *e;
+ BMLoop *l;
+
+ /* connected edge-verts */
+ BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == 0) {
+ BMVert *v_other = BM_edge_other_vert(e, v);
+ if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
+ BM_elem_flag_enable(v_other, BM_ELEM_TAG);
+ STACK_PUSH(queue_next, v_other);
+ }
+ }
+ }
+ }
- BLI_array_append(queue, v3);
- BLI_array_append(dqueue, d2);
+ /* connected face-verts (excluding adjacent verts) */
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ if ((BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) == 0) && (l->f->len > 3)) {
+ BMLoop *l_end = l->prev;
+ l = l->next->next;
+ do {
+ BMVert *v_other = l->v;
+ if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
+ BM_elem_flag_enable(v_other, BM_ELEM_TAG);
+ STACK_PUSH(queue_next, v_other);
+ }
+ }
+ } while ((l = l->next) != l_end);
+ }
+ }
}
-
- start++;
- }
- BLI_smallhash_release(visit);
-
- for (i = 0; i < em->bm->totvert; i++) {
- if (tots[i])
- dists[i] /= (float)tots[i];
- }
-
- BLI_array_free(queue);
- BLI_array_free(dqueue);
- MEM_freeN(tots);
+ /* clear for the next loop */
+ for (i = 0; i < STACK_SIZE(queue_next); i++) {
+ BM_elem_flag_disable(queue_next[i], BM_ELEM_TAG);
+ }
+
+ STACK_SWAP(queue, queue_next);
+
+ /* none should be tagged now since 'queue_next' is empty */
+ BLI_assert(BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
+
+ } while (STACK_SIZE(queue));
+
+ STACK_FREE(queue);
+ STACK_FREE(queue_next);
+
+ MEM_freeN(queue);
+ MEM_freeN(queue_next);
+ MEM_freeN(dists_prev);
}
static BMElem *bm_vert_single_select_face(BMVert *eve)
@@ -2099,7 +2131,7 @@ static void createTransEditVerts(TransInfo *t)
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
if (propmode & T_PROP_CONNECTED) {
- editmesh_set_connectivity_distance(em, mtx, dists);
+ editmesh_set_connectivity_distance(em->bm, mtx, dists);
}
/* detect CrazySpace [tm] */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 917335e2068..386eda7dd38 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2113,7 +2113,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
hitlen = hit.efa->len;
}
else if (selectmode == UV_SELECT_ISLAND) {
- uv_find_nearest_vert(scene, ima, em, co, NULL, &hit);
+ uv_find_nearest_edge(scene, ima, em, co, &hit);
if (hit.efa == NULL) {
return OPERATOR_CANCELLED;
@@ -2378,7 +2378,7 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
RNA_float_get_array(op->ptr, "location", co);
}
- uv_find_nearest_vert(scene, ima, em, co, NULL, &hit);
+ uv_find_nearest_edge(scene, ima, em, co, &hit);
hit_p = &hit;
}
diff --git a/source/blender/freestyle/intern/application/AppCanvas.cpp b/source/blender/freestyle/intern/application/AppCanvas.cpp
index e1f300b3ce0..f621f45ff77 100644
--- a/source/blender/freestyle/intern/application/AppCanvas.cpp
+++ b/source/blender/freestyle/intern/application/AppCanvas.cpp
@@ -136,8 +136,8 @@ void AppCanvas::readColorPixels(int x, int y, int w, int h, RGBImage& oImage) co
int ymin = border().getMin().y();
int xmax = border().getMax().x();
int ymax = border().getMax().y();
- int rectx = _pass_z.width;
- int recty = _pass_z.height;
+ int rectx = _pass_diffuse.width;
+ int recty = _pass_diffuse.height;
float xfac = ((float)rectx) / ((float)(xmax - xmin));
float yfac = ((float)recty) / ((float)(ymax - ymin));
#if 0
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a846ac697f0..e0c5cd5608e 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -360,6 +360,12 @@ typedef struct bAddon {
IDProperty *prop; /* User-Defined Properties on this Addon (for storing preferences) */
} bAddon;
+typedef struct bPathCompare {
+ struct bPathCompare *next, *prev;
+ char path[768]; /* FILE_MAXDIR */
+ char flag, pad[7];
+} bPathCompare;
+
typedef struct SolidLight {
int flag, pad;
float col[4], spec[4], vec[4];
@@ -412,6 +418,7 @@ typedef struct UserDef {
struct ListBase keymaps DNA_DEPRECATED; /* deprecated in favor of user_keymaps */
struct ListBase user_keymaps;
struct ListBase addons;
+ struct ListBase autoexec_paths;
char keyconfigstr[64];
short undosteps;
@@ -522,7 +529,12 @@ typedef enum eUserPref_Flag {
USER_TXT_TABSTOSPACES_DISABLE = (1 << 25),
USER_TOOLTIPS_PYTHON = (1 << 26),
} eUserPref_Flag;
-
+
+/* flag */
+typedef enum ePathCompare_Flag {
+ USER_PATHCMP_GLOB = (1 << 0),
+} ePathCompare_Flag;
+
/* helper macro for checking frame clamping */
#define FRAMENUMBER_MIN_CLAMP(cfra) { \
if ((U.flag & USER_NONEGFRAMES) && (cfra < 0)) \
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 36da4e3508c..4513694e59d 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -138,6 +138,25 @@ EnumPropertyItem clip_editor_mode_items[] = {
};
/* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */
+static EnumPropertyItem buttons_context_items[] = {
+ {BCONTEXT_SCENE, "SCENE", ICON_SCENE_DATA, "Scene", "Scene"},
+ {BCONTEXT_RENDER, "RENDER", ICON_SCENE, "Render", "Render"},
+ {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render layers"},
+ {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
+ {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
+ {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Object constraints"},
+ {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Object modifiers"},
+ {BCONTEXT_DATA, "DATA", ICON_NONE, "Data", "Object data"},
+ {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"},
+ {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone constraints"},
+ {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"},
+ {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"},
+ {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"},
+ {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+/* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */
static EnumPropertyItem buttons_texture_context_items[] = {
{SB_TEXC_MATERIAL, "MATERIAL", ICON_MATERIAL, "", "Show material textures"},
{SB_TEXC_WORLD, "WORLD", ICON_WORLD, "", "Show world textures"},
@@ -831,6 +850,76 @@ static void rna_SpaceProperties_context_set(PointerRNA *ptr, int value)
sbuts->mainbuser = value;
}
+static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *C, PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
+{
+ SpaceButs *sbuts = (SpaceButs *)(ptr->data);
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+
+ if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_RENDER_LAYER)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER_LAYER);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_CONSTRAINT);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MODIFIER);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_DATA);
+ (item + totitem - 1)->icon = sbuts->dataicon;
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE_CONSTRAINT);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MATERIAL);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TEXTURE);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PARTICLE);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PHYSICS);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+}
+
static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value)
{
SpaceButs *sbuts = (SpaceButs *)(ptr->data);
@@ -2068,24 +2157,6 @@ static void rna_def_space_buttons(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem buttons_context_items[] = {
- {BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"},
- {BCONTEXT_RENDER, "RENDER", ICON_SCENE_DATA, "Render", "Render"},
- {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render Layers"},
- {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
- {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
- {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"},
- {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifiers"},
- {BCONTEXT_DATA, "DATA", 0, "Data", "Data"},
- {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"},
- {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone Constraints"},
- {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"},
- {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"},
- {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"},
- {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"},
- {0, NULL, 0, NULL, NULL}
- };
-
static EnumPropertyItem align_items[] = {
{BUT_HORIZONTAL, "HORIZONTAL", 0, "Horizontal", ""},
{BUT_VERTICAL, "VERTICAL", 0, "Vertical", ""},
@@ -2099,7 +2170,7 @@ static void rna_def_space_buttons(BlenderRNA *brna)
prop = RNA_def_property(srna, "context", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mainb");
RNA_def_property_enum_items(prop, buttons_context_items);
- RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", NULL);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", "rna_SpaceProperties_context_itemf");
RNA_def_property_ui_text(prop, "Context", "Type of active data to display and edit");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 347c57f9044..f34366a23c7 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -339,9 +339,9 @@ static bAddon *rna_userdef_addon_new(void)
return bext;
}
-static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *bext_ptr)
+static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *path_cmp_ptr)
{
- bAddon *bext = bext_ptr->data;
+ bAddon *bext = path_cmp_ptr->data;
if (BLI_findindex(&U.addons, bext) == -1) {
BKE_report(reports, RPT_ERROR, "Addon is no longer valid");
return;
@@ -353,7 +353,26 @@ static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *bext_ptr)
}
BLI_freelinkN(&U.addons, bext);
- RNA_POINTER_INVALIDATE(bext_ptr);
+ RNA_POINTER_INVALIDATE(path_cmp_ptr);
+}
+
+static bPathCompare *rna_userdef_pathcompare_new(void)
+{
+ bPathCompare *path_cmp = MEM_callocN(sizeof(bPathCompare), "bPathCompare");
+ BLI_addtail(&U.autoexec_paths, path_cmp);
+ return path_cmp;
+}
+
+static void rna_userdef_pathcompare_remove(ReportList *reports, PointerRNA *path_cmp_ptr)
+{
+ bPathCompare *path_cmp = path_cmp_ptr->data;
+ if (BLI_findindex(&U.autoexec_paths, path_cmp) == -1) {
+ BKE_report(reports, RPT_ERROR, "Addon is no longer valid");
+ return;
+ }
+
+ BLI_freelinkN(&U.autoexec_paths, path_cmp);
+ RNA_POINTER_INVALIDATE(path_cmp_ptr);
}
static void rna_userdef_temp_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
@@ -2733,6 +2752,25 @@ static void rna_def_userdef_addon(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_Addon_preferences_get", NULL, NULL, NULL);
}
+static void rna_def_userdef_pathcompare(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "PathCompare", NULL);
+ RNA_def_struct_sdna(srna, "bPathCompare");
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Path Compare", "Match paths against this value");
+
+ prop = RNA_def_property(srna, "path", PROP_STRING, PROP_DIRPATH);
+ RNA_def_property_ui_text(prop, "Path", "");
+ RNA_def_struct_name_property(srna, prop);
+
+ prop = RNA_def_property(srna, "use_glob", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_PATHCMP_GLOB);
+ RNA_def_property_ui_text(prop, "Use Wildcard", "Enable wildcard globbing");
+}
+
static void rna_def_userdef_addon_pref(BlenderRNA *brna)
{
StructRNA *srna;
@@ -4027,6 +4065,32 @@ static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cpro
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
}
+static void rna_def_userdef_autoexec_path_collection(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "PathCompareCollection");
+ srna = RNA_def_struct(brna, "PathCompareCollection", NULL);
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Paths Compare", "Collection of paths");
+
+ func = RNA_def_function(srna, "new", "rna_userdef_pathcompare_new");
+ RNA_def_function_flag(func, FUNC_NO_SELF);
+ RNA_def_function_ui_description(func, "Add a new addon");
+ /* return type */
+ parm = RNA_def_pointer(func, "pathcmp", "PathCompare", "", "");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_userdef_pathcompare_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove path");
+ parm = RNA_def_pointer(func, "pathcmp", "PathCompare", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+}
+
void RNA_def_userdef(BlenderRNA *brna)
{
StructRNA *srna;
@@ -4074,6 +4138,11 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Addon", "");
rna_def_userdef_addon_collection(brna, prop);
+ prop = RNA_def_property(srna, "autoexec_paths", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "autoexec_paths", NULL);
+ RNA_def_property_struct_type(prop, "PathCompare");
+ RNA_def_property_ui_text(prop, "Autoexec Paths", "");
+ rna_def_userdef_autoexec_path_collection(brna, prop);
/* nested structs */
prop = RNA_def_property(srna, "view", PROP_POINTER, PROP_NONE);
@@ -4113,6 +4182,7 @@ void RNA_def_userdef(BlenderRNA *brna)
rna_def_userdef_system(brna);
rna_def_userdef_addon(brna);
rna_def_userdef_addon_pref(brna);
+ rna_def_userdef_pathcompare(brna);
}
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 6bf3beec57b..b70ab7c15f2 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -955,7 +955,7 @@ static int operator_execute(bContext *C, wmOperator *op)
}
/* same as execute() but no return value */
-static int operator_check(bContext *C, wmOperator *op)
+static bool operator_check(bContext *C, wmOperator *op)
{
extern FunctionRNA rna_Operator_check_func;
@@ -963,7 +963,7 @@ static int operator_check(bContext *C, wmOperator *op)
ParameterList list;
FunctionRNA *func;
void *ret;
- int result;
+ bool result;
RNA_pointer_create(NULL, op->type->ext.srna, op, &opr);
func = &rna_Operator_check_func; /* RNA_struct_find_function(&opr, "check"); */
@@ -973,7 +973,7 @@ static int operator_check(bContext *C, wmOperator *op)
op->type->ext.call(C, &opr, func, &list);
RNA_parameter_get_lookup(&list, "result", &ret);
- result = *(int *)ret;
+ result = (*(int *)ret) != 0;
RNA_parameter_list_free(&list);
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index d877932b81d..e37fc56d08c 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -49,7 +49,7 @@
#include "DNA_object_types.h"
-static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob))
+static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd)
{
DerivedMesh *result;
BMesh *bm;
@@ -97,7 +97,8 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
result = CDDM_from_bmesh(bm, TRUE);
BM_mesh_free(bm);
-
+
+ result->dirty |= DM_DIRTY_NORMALS;
return result;
}
@@ -119,25 +120,16 @@ static void copyData(ModifierData *md, ModifierData *target)
temd->flags = emd->flags;
}
-static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd,
- Object *ob, DerivedMesh *dm)
-{
- if (!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG)))
- return dm;
-
- return doEdgeSplit(dm, emd, ob);
-}
-
-static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData,
+static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *result;
EdgeSplitModifierData *emd = (EdgeSplitModifierData *) md;
- result = edgesplitModifier_do(emd, ob, derivedData);
+ if (!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG)))
+ return dm;
- if (result != derivedData)
- result->dirty |= DM_DIRTY_NORMALS;
+ result = doEdgeSplit(dm, emd);
return result;
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 189c30b02e8..72b54e2f1f7 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -112,6 +112,7 @@ bool WM_is_draw_triple(struct wmWindow *win);
/* files */
+void WM_file_autoexec_init(const char *filepath);
void WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports);
void WM_autosave_init(struct wmWindowManager *wm);
void WM_recover_last_session(struct bContext *C, struct ReportList *reports);
@@ -193,7 +194,7 @@ int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const str
int WM_operator_confirm (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
/* invoke callback, file selector "filepath" unset + exec */
int WM_operator_filesel (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
-int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format);
+bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format);
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index cb060077166..cd3899897a1 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -531,7 +531,7 @@ typedef struct wmOperatorType {
* is changed. It can correct its own properties or report errors for
* invalid settings in exceptional cases.
* Boolean return value, True denotes a change has been made and to redraw */
- int (*check)(struct bContext *, struct wmOperator *);
+ bool (*check)(struct bContext *, struct wmOperator *);
/* for modal temporary operators, initially invoke is called. then
* any further events are handled in modal. if the operation is
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index b6aecf120cc..f4b50667b2f 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -70,6 +70,7 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
+#include "BKE_autoexec.h"
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
@@ -364,6 +365,21 @@ static int wm_read_exotic(Scene *UNUSED(scene), const char *name)
return retval;
}
+void WM_file_autoexec_init(const char *filepath)
+{
+ if (G.f & G_SCRIPT_OVERRIDE_PREF) {
+ return;
+ }
+
+ if (G.f & G_SCRIPT_AUTOEXEC) {
+ char path[FILE_MAX];
+ BLI_split_dir_part(filepath, path, sizeof(path));
+ if (BKE_autoexec_match(path)) {
+ G.f &= ~G_SCRIPT_AUTOEXEC;
+ }
+ }
+}
+
void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
{
int retval;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 3d4bd2a1bc6..e71be6052d0 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -60,6 +60,7 @@
#include "BLO_readfile.h"
+#include "BKE_autoexec.h"
#include "BKE_blender.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -1038,7 +1039,7 @@ int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event
}
}
-int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
+bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
{
PropertyRNA *prop;
char filepath[FILE_MAX];
@@ -1868,6 +1869,47 @@ static void WM_OT_save_homefile(wmOperatorType *ot)
ot->poll = WM_operator_winactive;
}
+static int wm_userpref_autoexec_add_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
+{
+ bPathCompare *path_cmp = MEM_callocN(sizeof(bPathCompare), "bPathCompare");
+ BLI_addtail(&U.autoexec_paths, path_cmp);
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_userpref_autoexec_path_add(wmOperatorType *ot)
+{
+ ot->name = "Add Autoexec Path";
+ ot->idname = "WM_OT_userpref_autoexec_path_add";
+
+ ot->exec = wm_userpref_autoexec_add_exec;
+ ot->poll = WM_operator_winactive;
+
+ ot->flag = OPTYPE_INTERNAL;
+}
+
+static int wm_userpref_autoexec_remove_exec(bContext *UNUSED(C), wmOperator *op)
+{
+ const int index = RNA_int_get(op->ptr, "index");
+ bPathCompare *path_cmp = BLI_findlink(&U.autoexec_paths, index);
+ if (path_cmp) {
+ BLI_freelinkN(&U.autoexec_paths, path_cmp);
+ }
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_userpref_autoexec_path_remove(wmOperatorType *ot)
+{
+ ot->name = "Remove Autoexec Path";
+ ot->idname = "WM_OT_userpref_autoexec_path_remove";
+
+ ot->exec = wm_userpref_autoexec_remove_exec;
+ ot->poll = WM_operator_winactive;
+
+ ot->flag = OPTYPE_INTERNAL;
+
+ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
+}
+
static void WM_OT_save_userpref(wmOperatorType *ot)
{
ot->name = "Save User Settings";
@@ -1916,6 +1958,12 @@ static void WM_OT_read_factory_settings(wmOperatorType *ot)
/* *************** open file **************** */
+/* currently fits in a pointer */
+struct FileRuntime {
+ bool is_untrusted;
+};
+
+
static void open_set_load_ui(wmOperator *op, bool use_prefs)
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "load_ui");
@@ -1960,6 +2008,7 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *U
RNA_string_set(op->ptr, "filepath", openname);
open_set_load_ui(op, true);
open_set_use_scripts(op, true);
+ op->customdata = NULL;
WM_event_add_fileselect(C, op);
@@ -1990,11 +2039,65 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
/* do it before for now, but is this correct with multiple windows? */
WM_event_add_notifier(C, NC_WINDOW, NULL);
+ /* autoexec is already set correctly for invoke() for exec() though we need to initialize */
+ if (!RNA_struct_property_is_set(op->ptr, "use_scripts")) {
+ WM_file_autoexec_init(path);
+ }
WM_file_read(C, path, op->reports);
-
+
return OPERATOR_FINISHED;
}
+static bool wm_open_mainfile_check(bContext *UNUSED(C), wmOperator *op)
+{
+ struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts");
+ bool is_untrusted = false;
+ char path[FILE_MAX];
+ char *lslash;
+
+ RNA_string_get(op->ptr, "filepath", path);
+
+ /* get the dir */
+ lslash = (char *)BLI_last_slash(path);
+ if (lslash) *(lslash + 1) = '\0';
+
+ if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) {
+ if (BKE_autoexec_match(path) == true) {
+ RNA_property_boolean_set(op->ptr, prop, false);
+ is_untrusted = true;
+ }
+ }
+
+ if (file_info) {
+ file_info->is_untrusted = is_untrusted;
+ }
+
+ return is_untrusted;
+}
+
+static void wm_open_mainfile_ui(bContext *UNUSED(C), wmOperator *op)
+{
+ struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
+ uiLayout *layout = op->layout;
+ uiLayout *col = op->layout;
+ const char *autoexec_text = NULL;
+
+ uiItemR(layout, op->ptr, "load_ui", 0, NULL, ICON_NONE);
+
+ col = uiLayoutColumn(layout, false);
+ if (file_info->is_untrusted) {
+ autoexec_text = "Trusted Source [Untrusted Path]";
+ uiLayoutSetActive(col, false);
+ uiLayoutSetEnabled(col, false);
+ }
+ else {
+ autoexec_text = "Trusted Source";
+ }
+
+ uiItemR(col, op->ptr, "use_scripts", 0, autoexec_text, ICON_NONE);
+}
+
static void WM_OT_open_mainfile(wmOperatorType *ot)
{
ot->name = "Open Blender File";
@@ -2003,6 +2106,8 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
ot->invoke = wm_open_mainfile_invoke;
ot->exec = wm_open_mainfile_exec;
+ ot->check = wm_open_mainfile_check;
+ ot->ui = wm_open_mainfile_ui;
/* ommit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_OPENFILE,
@@ -2233,6 +2338,7 @@ void WM_recover_last_session(bContext *C, ReportList *reports)
WM_event_add_notifier(C, NC_WINDOW, NULL);
/* load file */
+ WM_file_autoexec_init(filename);
WM_file_read(C, filename, reports);
G.fileflags &= ~G_FILE_RECOVER;
@@ -2279,6 +2385,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_WINDOW, NULL);
/* load file */
+ WM_file_autoexec_init(path);
WM_file_read(C, path, op->reports);
G.fileflags &= ~G_FILE_RECOVER;
@@ -2400,7 +2507,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
}
/* function used for WM_OT_save_mainfile too */
-static int blend_save_check(bContext *UNUSED(C), wmOperator *op)
+static bool blend_save_check(bContext *UNUSED(C), wmOperator *op)
{
char filepath[FILE_MAX];
RNA_string_get(op->ptr, "filepath", filepath);
@@ -4044,6 +4151,8 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_read_factory_settings);
WM_operatortype_append(WM_OT_save_homefile);
WM_operatortype_append(WM_OT_save_userpref);
+ WM_operatortype_append(WM_OT_userpref_autoexec_path_add);
+ WM_operatortype_append(WM_OT_userpref_autoexec_path_remove);
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
WM_operatortype_append(WM_OT_quit_blender);
WM_operatortype_append(WM_OT_open_mainfile);
@@ -4101,13 +4210,12 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_SELECT);
-#if 0 /* Durien guys like this :S */
+ /* left mouse shift for deselect too */
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_DESELECT);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_NOP);
-#else
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_DESELECT); // default 2.4x
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP); // default 2.4x
-#endif
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP);
@@ -4175,21 +4283,22 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
+
/* Note: cancel only on press otherwise you cannot map this to RMB-gesture */
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
-
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
-#if 0 /* Durian guys like this */
+ /* allow shift leftclick for deselect too */
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_DESELECT);
-#else
+
+ /* any unhandled leftclick release handles select */
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_DESELECT);
-#endif
-
+
/* assign map to operators */
WM_modalkeymap_assign(keymap, "ACTION_OT_select_border");
WM_modalkeymap_assign(keymap, "ANIM_OT_channels_select_border");