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
path: root/source
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-11-14 06:01:02 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-11-14 06:01:02 +0400
commit6cee7bb2b77bc7b577a3067c30dc56e22b4752ce (patch)
treeab504ed0ffa59eb68ed1b57f2208dd949cf40fda /source
parent872af481831650f2399c85df2ed059d58c5210be (diff)
parentde5d0d649da9b73de96cbee9015b838e3c0389c1 (diff)
Merged changes in the trunk up to revision 52191.
Conflicts resolved: source/blender/makesdna/DNA_scene_types.h
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_modifier.h4
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h2
-rw-r--r--source/blender/blenkernel/SConscript1
-rw-r--r--source/blender/blenkernel/intern/colortools.c39
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c3
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c4
-rw-r--r--source/blender/blenkernel/intern/object.c18
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c19
-rw-r--r--source/blender/blenlib/intern/noise.c54
-rw-r--r--source/blender/blenloader/intern/versioning_250.c2
-rw-r--r--source/blender/bmesh/bmesh_class.h10
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c33
-rw-r--r--source/blender/bmesh/intern/bmesh_decimate_dissolve.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c20
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c37
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h4
-rw-r--r--source/blender/bmesh/operators/bmo_bevel.c287
-rw-r--r--source/blender/bmesh/operators/bmo_create.c6
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c4
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c2
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c2
-rw-r--r--source/blender/bmesh/operators/bmo_symmetrize.c2
-rw-r--r--source/blender/collada/AnimationImporter.cpp2
-rw-r--r--source/blender/compositor/operations/COM_PixelateOperation.h2
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c309
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c85
-rw-r--r--source/blender/editors/include/ED_mesh.h5
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c6
-rw-r--r--source/blender/editors/interface/interface_templates.c2
-rw-r--r--source/blender/editors/mesh/editmesh_add.c2
-rw-r--r--source/blender/editors/mesh/editmesh_bvh.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c4
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c48
-rw-r--r--source/blender/editors/mesh/editmesh_select.c220
-rw-r--r--source/blender/editors/mesh/mesh_intern.h1
-rw-r--r--source/blender/editors/mesh/mesh_ops.c1
-rw-r--r--source/blender/editors/object/object_modifier.c11
-rw-r--r--source/blender/editors/object/object_relations.c4
-rw-r--r--source/blender/editors/object/object_vgroup.c15
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_clip/clip_draw.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c54
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c106
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c18
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c2
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c6
-rw-r--r--source/blender/imbuf/intern/colormanagement.c2
-rw-r--r--source/blender/imbuf/intern/jp2.c4
-rw-r--r--source/blender/imbuf/intern/jpeg.c25
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp4
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_multi.h8
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h3
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesdna/DNA_tracking_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_curve.c2
-rw-r--r--source/blender/makesrna/intern/rna_wm.c6
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c2
-rw-r--r--source/blender/render/extern/include/RE_engine.h1
-rw-r--r--source/blender/render/intern/raytrace/rayobject_internal.h2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp2
-rw-r--r--source/blender/render/intern/source/external_engine.c24
-rw-r--r--source/blender/render/intern/source/pipeline.c5
-rw-r--r--source/blender/render/intern/source/sunsky.c4
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c30
-rw-r--r--source/blender/windowmanager/intern/wm_window.c2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h4
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp2
78 files changed, 1133 insertions, 516 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 7ee1c85d0de..2fa78b30835 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -319,8 +319,8 @@ int modifier_dependsOnTime(struct ModifierData *md);
int modifier_supportsMapping(struct ModifierData *md);
int modifier_couldBeCage(struct Scene *scene, struct ModifierData *md);
int modifier_isCorrectableDeformed(struct ModifierData *md);
-int modifier_sameTopology(ModifierData *md);
-int modifier_nonGeometrical(ModifierData *md);
+int modifier_isSameTopology(ModifierData *md);
+int modifier_isNonGeometrical(ModifierData *md);
int modifier_isEnabled(struct Scene *scene, struct ModifierData *md, int required_mode);
void modifier_setError(struct ModifierData *md, const char *format, ...)
#ifdef __GNUC__
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index ba611817c8f..88294cb30b6 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -248,7 +248,7 @@ void BKE_sequencer_cache_cleanup(void);
struct ImBuf *BKE_sequencer_cache_get(SeqRenderData context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type);
/* passed ImBuf is properly refed, so ownership is *not*
- * transfered to the cache.
+ * transferred to the cache.
* you can pass the same ImBuf multiple times to the cache without problems.
*/
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 155d4068c9a..1f04f4adba3 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -4,6 +4,7 @@ import os
sources = env.Glob('intern/*.c')
sources.remove('intern' + os.sep + 'mask_rasterize.c')
+sources.remove('intern' + os.sep + 'mask_evaluate.c')
sources.remove('intern' + os.sep + 'mask.c')
sources_mask = env.Glob('intern/mask*.c')
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 75276adf518..529fe07cab3 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1008,8 +1008,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
const ColorManagedDisplaySettings *display_settings)
{
int x, y, c;
- unsigned int n, nl;
- double div, divl;
+ unsigned int nl, na, nr, ng, nb;
+ double divl, diva, divr, divg, divb;
float *rf = NULL;
unsigned char *rc = NULL;
unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a;
@@ -1149,24 +1149,37 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
savedlines += 1;
}
+ /* test for nicer distribution even - non standard, leave it out for a while */
+#if 0
+ for (x = 0; x < 256; x++) {
+ bin_lum[x] = sqrt (bin_lum[x]);
+ bin_r[x] = sqrt(bin_r[x]);
+ bin_g[x] = sqrt(bin_g[x]);
+ bin_b[x] = sqrt(bin_b[x]);
+ bin_a[x] = sqrt(bin_a[x]);
+ }
+#endif
+
/* convert hist data to float (proportional to max count) */
- n = 0;
- nl = 0;
+ nl = na = nr = nb = ng = 0;
for (x = 0; x < 256; x++) {
if (bin_lum[x] > nl) nl = bin_lum[x];
- if (bin_r[x] > n) n = bin_r[x];
- if (bin_g[x] > n) n = bin_g[x];
- if (bin_b[x] > n) n = bin_b[x];
- if (bin_a[x] > n) n = bin_a[x];
+ if (bin_r[x] > nr) nr = bin_r[x];
+ if (bin_g[x] > ng) ng = bin_g[x];
+ if (bin_b[x] > nb) nb = bin_b[x];
+ if (bin_a[x] > na) na = bin_a[x];
}
- div = 1.0 / (double)n;
divl = 1.0 / (double)nl;
+ diva = 1.0 / (double)na;
+ divr = 1.0 / (double)nr;
+ divg = 1.0 / (double)ng;
+ divb = 1.0 / (double)nb;
for (x = 0; x < 256; x++) {
scopes->hist.data_luma[x] = bin_lum[x] * divl;
- scopes->hist.data_r[x] = bin_r[x] * div;
- scopes->hist.data_g[x] = bin_g[x] * div;
- scopes->hist.data_b[x] = bin_b[x] * div;
- scopes->hist.data_a[x] = bin_a[x] * div;
+ scopes->hist.data_r[x] = bin_r[x] * divr;
+ scopes->hist.data_g[x] = bin_g[x] * divg;
+ scopes->hist.data_b[x] = bin_b[x] * divb;
+ scopes->hist.data_a[x] = bin_a[x] * diva;
}
MEM_freeN(bin_lum);
MEM_freeN(bin_r);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 9d3a7ec57cf..d23a608d31f 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -671,8 +671,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
}
}
- else if(ob->type == OB_LAMP)
+ else if (ob->type == OB_LAMP) {
dag_add_lamp_driver_relations(dag, node, ob->data);
+ }
/* particles */
psys = ob->particlesystem.first;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 068059dc29a..fd5af6a20bb 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -3011,7 +3011,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
MLoop *l_iter = loopstart;
float area, polynorm_local[3], (*vertexcos)[3];
const float *no = polynormal ? polynormal : polynorm_local;
- BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__);
+ BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__);
/* pack vertex cos into an array for area_poly_v3 */
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 9c7cbc42bdd..25b70ce1793 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -249,13 +249,13 @@ int modifier_couldBeCage(struct Scene *scene, ModifierData *md)
modifier_supportsMapping(md));
}
-int modifier_sameTopology(ModifierData *md)
+int modifier_isSameTopology(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
}
-int modifier_nonGeometrical(ModifierData *md)
+int modifier_isNonGeometrical(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return (mti->type == eModifierTypeType_NonGeometrical);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 7e3808512b6..9ea1c3e8c74 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -198,18 +198,18 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
return TRUE;
}
-void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
+void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
{
ModifierData *md;
- BKE_object_free_modifiers(ob);
+ BKE_object_free_modifiers(ob_dst);
- if (!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
+ if (!ELEM5(ob_dst->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
/* only objects listed above can have modifiers and linking them to objects
* which doesn't have modifiers stack is quite silly */
return;
}
- for (md = from->modifiers.first; md; md = md->next) {
+ for (md = ob_src->modifiers.first; md; md = md->next) {
ModifierData *nmd = NULL;
if (ELEM4(md->type,
@@ -221,16 +221,18 @@ void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
continue;
}
- if (!BKE_object_support_modifier_type_check(ob, md->type))
+ if (!BKE_object_support_modifier_type_check(ob_dst, md->type))
continue;
nmd = modifier_new(md->type);
+ BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
modifier_copyData(md, nmd);
- BLI_addtail(&ob->modifiers, nmd);
+ BLI_addtail(&ob_dst->modifiers, nmd);
+ modifier_unique_name(&ob_dst->modifiers, nmd);
}
- BKE_object_copy_particlesystems(ob, from);
- BKE_object_copy_softbody(ob, from);
+ BKE_object_copy_particlesystems(ob_dst, ob_src);
+ BKE_object_copy_softbody(ob_dst, ob_src);
/* TODO: smoke?, cloth? */
}
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index f27da759482..8dccded64d1 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -139,6 +139,25 @@ MINLINE int power_of_2_min_i(int n)
return n;
}
+MINLINE unsigned int highest_order_bit_i(unsigned int n)
+{
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ n |= (n >> 16);
+ return n - (n >> 1);
+}
+
+MINLINE unsigned short highest_order_bit_s(unsigned short n)
+{
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ return n - (n >> 1);
+}
+
MINLINE float min_ff(float a, float b)
{
return (a < b) ? a : b;
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index fb33d7ce127..6bb59e1e195 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -456,16 +456,50 @@ float BLI_turbulence1(float noisesize, float x, float y, float z, int nr)
/* ********************* FROM PERLIN HIMSELF: ******************** */
-static char p[512 + 2] = {
- 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
- 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
- 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
- 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
- 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
- 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
- 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
- 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
- 0xA2, 0xA0
+static const char p[512 + 2] = {
+ 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28,
+ 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D,
+ 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8,
+ 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
+ 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13,
+ 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB,
+ 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB,
+ 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
+ 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C,
+ 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93,
+ 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F,
+ 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
+ 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2,
+ 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9,
+ 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5,
+ 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
+ 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8,
+ 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4,
+ 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3,
+ 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
+ 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75,
+ 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE,
+ 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F,
+ 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
+ 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83,
+ 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8,
+ 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D,
+ 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
+ 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98,
+ 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4,
+ 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA,
+ 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
+ 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E,
+ 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F,
+ 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0,
+ 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
+ 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10,
+ 0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4,
+ 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8,
+ 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
+ 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E,
+ 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A,
+ 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0
};
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index d75339252d9..1521739258e 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -901,7 +901,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
ob->matbits = MEM_callocN(sizeof(char)*ob->totcol, "ob->matbits");
for (a = 0; a < ob->totcol; a++)
- ob->matbits[a] = ob->colbits & (1<<a);
+ ob->matbits[a] = (ob->colbits & (1<<a)) != 0;
}
}
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index bdca3011714..af5a5719866 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -244,10 +244,16 @@ enum {
# define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
#endif
-/* size to use for static arrays when dealing with NGons,
+/**
+ * size to use for stack arrays when dealing with NGons,
* alloc after this limit is reached.
* this value is rather arbitrary */
-#define BM_NGON_STACK_SIZE 32
+#define BM_DEFAULT_NGON_STACK_SIZE 32
+/**
+ * size to use for stack arrays dealing with connected mesh data
+ * verts of faces, edges of vert - etc.
+ * often used with #BM_iter_as_arrayN() */
+#define BM_DEFAULT_ITER_STACK_SIZE 16
/* avoid inf loop, this value is arbitrary
* but should not error on valid cases */
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index 64fa1ea399d..5dd090c523d 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -174,9 +174,9 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f)
BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble)
{
BMEdge **edges2 = NULL;
- BLI_array_staticdeclare(edges2, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
BMVert **verts = NULL;
- BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
BMFace *f = NULL;
BMEdge *e;
BMVert *v, *ev1, *ev2;
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 0910dd82701..c427734f58d 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -195,8 +195,8 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
{
BMVert **verts = NULL;
BMEdge **edges = NULL;
- BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
- BLI_array_fixedstack_declare(edges, BM_NGON_STACK_SIZE, f->len, __func__);
+ BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
+ BLI_array_fixedstack_declare(edges, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
BMLoop *l_iter;
BMLoop *l_first;
BMLoop *l_copy;
@@ -558,7 +558,7 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
void BM_face_edges_kill(BMesh *bm, BMFace *f)
{
BMEdge **edges = NULL;
- BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
BMLoop *l_iter;
BMLoop *l_first;
int i;
@@ -582,7 +582,7 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
void BM_face_verts_kill(BMesh *bm, BMFace *f)
{
BMVert **verts = NULL;
- BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
BMLoop *l_iter;
BMLoop *l_first;
int i;
@@ -734,7 +734,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
BMLoop *l_iter, *oldprev, *oldnext;
BMEdge **edar = NULL;
- BLI_array_fixedstack_declare(edar, BM_NGON_STACK_SIZE, len, __func__);
+ BLI_array_fixedstack_declare(edar, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
int i, j, edok;
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
@@ -937,9 +937,9 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
BMEdge **edges = NULL;
BMEdge **deledges = NULL;
BMVert **delverts = NULL;
- BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
- BLI_array_staticdeclare(deledges, BM_NGON_STACK_SIZE);
- BLI_array_staticdeclare(delverts, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(deledges, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(delverts, BM_DEFAULT_NGON_STACK_SIZE);
BMVert *v1 = NULL, *v2 = NULL;
const char *err = NULL;
int i, tote = 0;
@@ -1587,7 +1587,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
if (LIKELY(radlen)) {
BMLoop **loops = NULL;
- BLI_array_fixedstack_declare(loops, BM_NGON_STACK_SIZE, radlen, __func__);
+ BLI_array_fixedstack_declare(loops, BM_DEFAULT_NGON_STACK_SIZE, radlen, __func__);
killoop = ke->l;
@@ -1808,23 +1808,28 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
*/
int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
{
- BMEdge *e;
-
+ void *loops_stack[BM_DEFAULT_ITER_STACK_SIZE];
BMLoop **loops;
int i, loops_tot;
+ BMEdge *e;
+
/* verts already spliced */
if (v == v_target) {
return FALSE;
}
/* we can't modify the vert while iterating so first allocate an array of loops */
- loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot);
- if (loops) {
+ loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot,
+ loops_stack, BM_DEFAULT_ITER_STACK_SIZE);
+
+ if (LIKELY(loops != NULL)) {
for (i = 0; i < loops_tot; i++) {
loops[i]->v = v_target;
}
- MEM_freeN(loops);
+ if (loops != (BMLoop **)loops_stack) {
+ MEM_freeN(loops);
+ }
}
/* move all the edges from v's disk to vtarget's disk */
diff --git a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c b/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
index d1371a18160..fb78050988d 100644
--- a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
@@ -231,8 +231,8 @@ void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_
int vinput_len;
int einput_len;
- BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len);
- BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len);
+ BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len, NULL, 0);
+ BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len, NULL, 0);
BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries,
vinput_arr, vinput_len,
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 508b3b8fcdf..caf9f3c70d5 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -174,9 +174,9 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
void **blocks = NULL;
float (*cos)[3] = NULL, *w = NULL;
- BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
int i;
BM_elem_attrs_copy(bm, bm, source, target);
@@ -613,10 +613,10 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
void **vblocks = NULL;
float (*cos)[3] = NULL, co[3], *w = NULL;
float cent[3] = {0.0f, 0.0f, 0.0f};
- BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(vblocks, BM_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
+ BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(vblocks, BM_DEFAULT_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
int i, ax, ay;
BM_elem_attrs_copy(bm, bm, source, target->f);
@@ -689,9 +689,9 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
void **blocks = NULL;
float (*cos)[3] = NULL, *w = NULL;
float cent[3] = {0.0f, 0.0f, 0.0f};
- BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
int i;
i = 0;
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 1cb95d94e9b..c3f33eb95e1 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -116,10 +116,14 @@ int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, cons
*
* Caller needs to free the array.
*/
-void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
+void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
+ /* optional args to avoid an alloc (normally stack array) */
+ void **stack_array, int stack_array_size)
{
BMIter iter;
+ BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
+
/* we can't rely on coun't being set */
switch (itype) {
case BM_VERTS_OF_MESH:
@@ -137,7 +141,9 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) {
BMElem *ele;
- BMElem **array = MEM_mallocN(sizeof(ele) * iter.count, __func__);
+ BMElem **array = iter.count > stack_array_size ?
+ MEM_mallocN(sizeof(ele) * iter.count, __func__) :
+ stack_array;
int i = 0;
*r_len = iter.count; /* set before iterating */
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index 3c42b3d610c..c0eefc2a3aa 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -125,7 +125,8 @@ __attribute__((warn_unused_result))
#endif
;
int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len);
-void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
+void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
+ void **stack_array, int stack_array_size)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 98edceb30a2..35213c83097 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -162,7 +162,7 @@ float BM_face_calc_area(BMFace *f)
float area;
int i;
- BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
+ BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
copy_v3_v3(verts[i], l->v->co);
@@ -965,8 +965,8 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f;
int i, j, a = 0, clen;
- BLI_array_fixedstack_declare(projverts, BM_NGON_STACK_SIZE, f->len, "projvertsb");
- BLI_array_fixedstack_declare(edgeverts, BM_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
+ BLI_array_fixedstack_declare(projverts, BM_DEFAULT_NGON_STACK_SIZE, f->len, "projvertsb");
+ BLI_array_fixedstack_declare(edgeverts, BM_DEFAULT_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
i = 0;
l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 1e1d7d1becb..cae9b5b3b83 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -1393,7 +1393,7 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
int BM_face_exists_multi_edge(BMEdge **earr, int len)
{
BMVert **varr;
- BLI_array_fixedstack_declare(varr, BM_NGON_STACK_SIZE, len, __func__);
+ BLI_array_fixedstack_declare(varr, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
int ok;
int i, i_next;
@@ -1419,3 +1419,38 @@ int BM_face_exists_multi_edge(BMEdge **earr, int len)
return ok;
}
+
+/* convenience functions for checking flags */
+int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
+{
+ return (BM_elem_flag_test(e->v1, hflag) ||
+ BM_elem_flag_test(e->v2, hflag));
+}
+
+int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->v, hflag)) {
+ return TRUE;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ return FALSE;
+}
+
+int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->e, hflag)) {
+ return TRUE;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ return FALSE;
+}
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 579a1397b0c..7bb456df8e8 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -100,4 +100,8 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
BMLoop *edge_loop);
+int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
+int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
+int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
+
#endif /* __BMESH_QUERIES_H__ */
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index 7df5aa8fe9c..db5b769d078 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -84,6 +84,8 @@ typedef struct VMesh {
M_POLY, /* a simple polygon */
M_ADJ, /* "adjacent edges" mesh pattern */
M_CROSS, /* "cross edges" mesh pattern */
+ M_TRI_FAN, /* a simple polygon - fan filled */
+ M_QUAD_STRIP, /* a simple polygon - cut into paralelle strips */
} mesh_kind;
int count; /* number of vertices in the boundary */
int seg; /* common # of segments for segmented edges */
@@ -187,10 +189,10 @@ static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e)
from_e = &bv->edges[bv->edgecount - 1];
e = from_e;
do {
- if (e->isbev)
+ if (e->isbev) {
return e;
- e = e->next;
- } while (e != from_e);
+ }
+ } while ((e = e->next) != from_e);
return NULL;
}
@@ -384,10 +386,9 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
madd_v3_v3fl(off2a, norm_perp2, e2->offset);
add_v3_v3v3(off2b, off2a, dir2);
- /* intersect the lines; by construction they should be on the same plane and not parallel */
if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
- BLI_assert(!"offset_meet failure");
- copy_v3_v3(meetco, off1a); /* just to do something */
+ /* lines are parallel; off1a is a good meet point */
+ copy_v3_v3(meetco, off1a);
}
}
@@ -440,8 +441,7 @@ static void project_to_edge(BMEdge *e, float co_a[3], float co_b[3], float projc
{
float otherco[3];
- if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b,
- projco, otherco)) {
+ if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b, projco, otherco)) {
BLI_assert(!"project meet failure");
copy_v3_v3(projco, e->v1->co);
}
@@ -537,10 +537,10 @@ static void get_point_on_round_edge(EdgeHalf *e, int i,
get_point_on_round_profile(point, e->offset, i, n, vaadj, vmid, vbadj);
- add_v3_v3v3(p2, profileco, dir);
+ add_v3_v3v3(p2, point, dir);
cross_v3_v3v3(pn, vva, vvb);
if (!isect_line_plane_v3(profileco, point, p2, vmid, pn, 0)) {
- BLI_assert(!"bevel: unexpected non-intersection");
+ /* TODO: track down why this sometimes fails */
copy_v3_v3(profileco, point);
}
}
@@ -639,10 +639,9 @@ static void build_boundary(BevVert *bv)
/* e is not beveled */
if (e->next->isbev) {
/* next iteration will place e between beveled previous and next edges */
- e = e->next;
- continue;
+ /* do nothing... */
}
- if (e->prev->isbev) {
+ else if (e->prev->isbev) {
/* on-edge meet between e->prev and e */
offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
v = add_new_bound_vert(vm, co);
@@ -663,16 +662,28 @@ static void build_boundary(BevVert *bv)
e->leftv = v;
}
}
- e = e->next;
- } while (e != efirst);
+ } while ((e = e->next) != efirst);
BLI_assert(vm->count >= 2);
- if (vm->count == 2 && bv->edgecount == 3)
+ if (vm->count == 2 && bv->edgecount == 3) {
vm->mesh_kind = M_NONE;
- else if (efirst->seg == 1 || bv->selcount < 3)
- vm->mesh_kind = M_POLY;
- else
- vm->mesh_kind = M_ADJ;
+ }
+ else if (efirst->seg == 1 || bv->selcount == 1) {
+ if (vm->count == 3 && bv->selcount == 1) {
+ vm->mesh_kind = M_TRI_FAN;
+ }
+ else {
+ vm->mesh_kind = M_POLY;
+ }
+ }
+ else {
+ if (bv->selcount == 2) {
+ vm->mesh_kind = M_QUAD_STRIP;
+ }
+ else {
+ vm->mesh_kind = M_ADJ;
+ }
+ }
/* TODO: if vm->count == 4 and bv->selcount == 4, use M_CROSS pattern */
}
@@ -694,8 +705,9 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
ns = vm->seg;
ns2 = ns / 2;
BLI_assert(n > 2 && ns > 1);
-
- /* Make initial rings, going between points on neighbors */
+ /* Make initial rings, going between points on neighbors.
+ * After this loop, will have coords for all (i, r, k) where
+ * BoundVert for i has a bevel, 0 <= r <= ns2, 0 <= k <= ns */
for (ring = 1; ring <= ns2; ring++) {
v = vm->boundstart;
do {
@@ -732,11 +744,15 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
}
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
}
- /* Now make sure cross points of rings share coordinates and vertices */
+ /* Now make sure cross points of rings share coordinates and vertices.
+ * After this loop, will have BMVerts for all (i, r, k) where
+ * i is for a BoundVert that is beveled and has either a predecessor or
+ * successor BoundVert beveled too, and
+ * for odd ns: 0 <= r <= ns2, 0 <= k <= ns
+ * for even ns: 0 <= r < ns2, 0 <= k <= ns except k=ns2 */
v = vm->boundstart;
do {
i = v->index;
@@ -777,11 +793,13 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
}
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
if (ns % 2 == 0) {
- /* do special case center lines */
+ /* Do special case center lines.
+ * This loop makes verts for (i, ns2, k) for 1 <= k <= ns-1, k!=ns2
+ * and for (i, r, ns2) for 1 <= r <= ns2-1,
+ * whenever i is in a sequence of at least two beveled verts */
v = vm->boundstart;
do {
i = v->index;
@@ -807,17 +825,20 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
copy_v3_v3(nv->co, co);
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
+
+ create_mesh_bmvert(bm, vm, i, ns2, ns - k, bv->v);
}
else if (vnext->ebev) {
mid_v3_v3v3(co, nv->co, nvnext->co);
copy_v3_v3(nv->co, co);
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
+
+ create_mesh_bmvert(bm, vm, i, ns2, k, bv->v);
}
}
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
/* center point need to be average of all centers of rings */
/* TODO: this is wrong if not all verts have ebev: could have
@@ -832,8 +853,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
add_v3_v3(midco, nv->co);
nn++;
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
mul_v3_fl(midco, 1.0f / nn);
bmv = BM_vert_create(bm, midco, NULL);
v = vm->boundstart;
@@ -844,8 +864,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
copy_v3_v3(nv->co, midco);
nv->v = bmv;
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
}
/* Make the ring quads */
@@ -871,15 +890,19 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
i = v->prev->index;
f = boundvert_rep_face(v->prev);
for (k = ns2 + (ns % 2); k < ns; k++) {
- bmv1 = mesh_vert(vm, i, ring + 1, k)->v;
- bmv2 = mesh_vert(vm, i, ring, k)->v;
- bmv3 = mesh_vert(vm, i, ring, k + 1)->v;
- BLI_assert(bmv1 && bmv2 && bmv3);
- bev_create_quad_tri(bm, bmv1, bmv2, bmv3, NULL, f);
+ bmv1 = mesh_vert(vm, i, ring, k)->v;
+ bmv2 = mesh_vert(vm, i, ring, k + 1)->v;
+ bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v;
+ bmv4 = mesh_vert(vm, i, ring + 1, k)->v;
+ BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
+ if (bmv2 == bmv3) {
+ bmv3 = bmv4;
+ bmv4 = NULL;
+ }
+ bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f);
}
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
}
/* Make center ngon if odd number of segments and fully beveled */
@@ -892,8 +915,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
i = v->index;
BLI_assert(v->ebev);
BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v);
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
f = boundvert_rep_face(vm->boundstart);
bev_create_ngon(bm, vv, BLI_array_count(vv), f);
@@ -915,21 +937,30 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
if (!v->prev->ebev) {
for (k = 0; k < ns2; k++) {
bmv1 = mesh_vert(vm, i, ns2, k)->v;
+ if (!bmv1)
+ bmv1 = mesh_vert(vm, i, 0, k)->v;
if (!(j > 0 && bmv1 == vv[j - 1])) {
+ BLI_assert(bmv1 != NULL);
BLI_array_append(vv, bmv1);
j++;
}
}
}
bmv1 = mesh_vert(vm, i, ns2, ns2)->v;
+ if (!bmv1)
+ bmv1 = mesh_vert(vm, i, 0, ns2)->v;
if (!(j > 0 && bmv1 == vv[j - 1])) {
+ BLI_assert(bmv1 != NULL);
BLI_array_append(vv, bmv1);
j++;
}
if (!v->next->ebev) {
for (k = ns - ns2; k < ns; k++) {
bmv1 = mesh_vert(vm, i, ns2, k)->v;
+ if (!bmv1)
+ bmv1 = mesh_vert(vm, i, 0, k)->v;
if (!(j > 0 && bmv1 == vv[j - 1])) {
+ BLI_assert(bmv1 != NULL);
BLI_array_append(vv, bmv1);
j++;
}
@@ -937,11 +968,11 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
}
else {
+ BLI_assert(mesh_vert(vm, i, 0, 0)->v != NULL);
BLI_array_append(vv, mesh_vert(vm, i, 0, 0)->v);
j++;
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
if (vv[0] == vv[j - 1])
j--;
bev_create_ngon(bm, vv, j, f);
@@ -950,8 +981,9 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
}
-static void bevel_build_poly(BMesh *bm, BevVert *bv)
+static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv)
{
+ BMFace *f;
int n, k;
VMesh *vm = bv->vmesh;
BoundVert *v;
@@ -970,11 +1002,91 @@ static void bevel_build_poly(BMesh *bm, BevVert *bv)
n++;
}
}
- v = v->next;
- } while (v != vm->boundstart);
- if (n > 2)
- bev_create_ngon(bm, vv, n, boundvert_rep_face(v));
+ } while ((v = v->next) != vm->boundstart);
+ if (n > 2) {
+ f = bev_create_ngon(bm, vv, n, boundvert_rep_face(v));
+ }
+ else {
+ f = NULL;
+ }
BLI_array_free(vv);
+ return f;
+}
+
+static void bevel_build_poly(BMesh *bm, BevVert *bv)
+{
+ bevel_build_poly_ex(bm, bv);
+}
+
+static void bevel_build_trifan(BMesh *bm, BevVert *bv)
+{
+ BMFace *f;
+ BLI_assert(next_bev(bv, NULL)->seg == 1 || bv->selcount == 1);
+
+ f = bevel_build_poly_ex(bm, bv);
+
+ if (f) {
+ /* we have a polygon which we know starts at the previous vertex, make it into a fan */
+ BMLoop *l_fan = BM_FACE_FIRST_LOOP(f)->prev;
+ BMVert *v_fan = l_fan->v;
+
+ while (f->len > 3) {
+ BMLoop *l_new;
+ BMFace *f_new;
+ BLI_assert(v_fan == l_fan->v);
+ f_new = BM_face_split(bm, f, l_fan->v, l_fan->next->next->v, &l_new, NULL, FALSE);
+
+ if (f_new->len > f->len) {
+ f = f_new;
+ if (l_new->v == v_fan) { l_fan = l_new; }
+ else if (l_new->next->v == v_fan) { l_fan = l_new->next; }
+ else if (l_new->prev->v == v_fan) { l_fan = l_new->prev; }
+ else { BLI_assert(0); }
+ }
+ else {
+ if (l_fan->v == v_fan) { l_fan = l_fan; }
+ else if (l_fan->next->v == v_fan) { l_fan = l_fan->next; }
+ else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; }
+ else { BLI_assert(0); }
+ }
+ }
+ }
+}
+
+static void bevel_build_quadstrip(BMesh *bm, BevVert *bv)
+{
+ BMFace *f;
+ BLI_assert(bv->selcount == 2);
+
+ f = bevel_build_poly_ex(bm, bv);
+
+ if (f) {
+ /* we have a polygon which we know starts at this vertex, make it into strips */
+ BMVert *v_first = bv->vmesh->boundstart->efirst->next->next->leftv->nv.v; /* magic? */
+ //BMLoop *l_start = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_start = BM_face_vert_share_loop(f, v_first);
+ BMLoop *l_a = l_start->prev, *l_a_step;
+ BMLoop *l_b = l_start->next, *l_b_step;
+
+ while (f->len > 4) {
+ // BMLoop *l_new;
+ BMFace *f_new;
+ BLI_assert(l_a->f == f);
+ BLI_assert(l_b->f == f);
+
+ l_a_step = l_a->prev;
+ l_b_step = l_b->next;
+
+ f_new = BM_face_split(bm, f, l_a->v, l_b->v, NULL, NULL, FALSE);
+
+ if (f_new->len > f->len) {
+ f = f_new;
+ }
+
+ l_a = l_a_step;
+ l_b = l_b_step;
+ }
+ }
}
/* Given that the boundary is built, now make the actual BMVerts
@@ -1009,8 +1121,7 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
else
weld2 = v;
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
/* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */
v = vm->boundstart;
@@ -1028,13 +1139,14 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
}
}
- v = v->next;
- } while (v != vm->boundstart);
+ } while ((v = v->next) != vm->boundstart);
if (weld) {
+ vm->mesh_kind = M_NONE;
for (k = 1; k < ns; k++) {
- mid_v3_v3v3(co, mesh_vert(vm, weld1->index, 0, k)->co,
- mesh_vert(vm, weld2->index, 0, ns - k)->co);
+ va = mesh_vert(vm, weld1->index, 0, k)->co;
+ vb = mesh_vert(vm, weld2->index, 0, ns - k)->co;
+ mid_v3_v3v3(co, va, vb);
copy_v3_v3(mesh_vert(vm, weld1->index, 0, k)->co, co);
create_mesh_bmvert(bm, vm, weld1->index, 0, k, bv->v);
}
@@ -1046,6 +1158,10 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
bevel_build_rings(bm, bv);
else if (vm->mesh_kind == M_POLY)
bevel_build_poly(bm, bv);
+ else if (vm->mesh_kind == M_TRI_FAN)
+ bevel_build_trifan(bm, bv);
+ else if (vm->mesh_kind == M_QUAD_STRIP)
+ bevel_build_quadstrip(bm, bv);
}
/*
@@ -1065,10 +1181,14 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMOperator *op, BMV
int nsel = 0;
/* Gather input selected edges.
- * Only bevel selected edges that have exactly two incident faces. */
+ * Only bevel selected edges that have exactly two incident faces.
+ *
+ * TODO, optimization - we could tag edges in 'geom'
+ * and then just iterate edges-of-vert, checking tags.
+ */
BMO_ITER (bme, &siter, bm, op, "geom", BM_EDGE) {
- if ((bme->v1 == v) || (BM_edge_other_vert(bme, bme->v1) == v)) {
- if (BM_edge_face_count(bme) == 2) {
+ if (BM_vert_in_edge(bme, v)) {
+ if (BM_edge_is_manifold(bme)) {
BMO_elem_flag_enable(bm, bme, EDGE_SELECTED);
nsel++;
}
@@ -1236,19 +1356,21 @@ static void rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
/* All polygons touching v need rebuilding because beveling v has made new vertices */
static void bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v)
{
- BMFace *f;
- BMIter iter;
+ void *faces_stack[BM_DEFAULT_ITER_STACK_SIZE];
+ int faces_len, f_index;
+ BMFace **faces = BM_iter_as_arrayN(bm, BM_FACES_OF_VERT, v, &faces_len,
+ faces_stack, BM_DEFAULT_ITER_STACK_SIZE);
+
+ if (LIKELY(faces != NULL)) {
+ for (f_index = 0; f_index < faces_len; f_index++) {
+ BMFace *f = faces[f_index];
+ rebuild_polygon(bm, bp, f);
+ BM_face_kill(bm, f);
+ }
- /* TODO: don't iterate through all faces, but just local geometry around v */
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- BMLoop *l = f->l_first;
- do {
- if (l->v == v) {
- rebuild_polygon(bm, bp, f);
- BM_face_kill(bm, f);
- }
- l = l->next;
- } while (l != f->l_first);
+ if (faces != (BMFace **)faces_stack) {
+ MEM_freeN(faces);
+ }
}
}
@@ -1266,7 +1388,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
BMFace *f1, *f2, *f;
int k, nseg, i1, i2;
- if (BM_edge_face_count(bme) != 2)
+ if (!BM_edge_is_manifold(bme))
return;
bv1 = find_bevvert(bp, bme->v1);
@@ -1279,12 +1401,12 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
BLI_assert(e1 && e2);
- /* v4 v3
- * \ /
- * e->v1 - e->v2
- * / \
- * v1 v2 */
-
+ /* v4 v3
+ * \ /
+ * e->v1 - e->v2
+ * / \
+ * v1 v2
+ */
nseg = e1->seg;
BLI_assert(nseg > 0 && nseg == e2->seg);
@@ -1334,8 +1456,7 @@ static void free_bevel_params(BevelParams *bp)
do {
vnext = v->next;
MEM_freeN(v);
- v = vnext;
- } while (v != vm->boundstart);
+ } while ((v = vnext) != vm->boundstart);
}
if (vm->mesh)
MEM_freeN(vm->mesh);
@@ -1349,15 +1470,13 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMVert *v;
BMEdge *e;
- BevelParams bp;
+ BevelParams bp = {{NULL}};
bp.offset = BMO_slot_float_get(op, "offset");
bp.op = op;
bp.seg = BMO_slot_int_get(op, "segments");
if (bp.offset > 0) {
- bp.vertList.first = bp.vertList.last = NULL;
-
/* The analysis of the input vertices and execution additional constructions */
BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
bevel_vert_construct(bm, &bp, op, v);
@@ -1563,7 +1682,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_disable(bm, e->v2, BEVEL_DEL);
}
#if 0
- if (BM_edge_face_count(e) == 0) {
+ if (BM_edge_is_wire(e)) {
BMVert *verts[2] = {e->v1, e->v2};
BMEdge *edges[2] = {e, BM_edge_create(bm, e->v1, e->v2, e, 0)};
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index 093f567d995..49a2f959063 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -168,7 +168,7 @@ static void rotsys_reverse(BMEdge *UNUSED(e), BMVert *v, EdgeData *edata, VertDa
BMEdge **edges = NULL;
BMEdge *e_first;
BMEdge *e;
- BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
int i, totedge;
e = e_first = vdata[BM_elem_index_get(v)].e;
@@ -359,10 +359,10 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
BMIter iter;
BMEdge *e;
BMEdge **edges = NULL;
- BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
BMVert *v;
/* BMVert **verts = NULL; */
- /* BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE); */ /* UNUSE */
+ /* BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); */ /* UNUSE */
int i;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 627351ead11..71048e18335 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -595,10 +595,10 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
/* array for passing verts to angle_poly_v3 */
float **verts = NULL;
- BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
/* array for receiving angles from angle_poly_v3 */
float *face_angles = NULL;
- BLI_array_staticdeclare(face_angles, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(face_angles, BM_DEFAULT_NGON_STACK_SIZE);
BM_mesh_elem_index_ensure(bm, BM_VERT);
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index b9c9398fbfa..80bdf9de7ed 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -385,7 +385,7 @@ static void hull_tag_holes(BMesh *bm, BMOperator *op)
BMO_ITER (f, &oiter, bm, op, "input", BM_FACE) {
if (BMO_elem_flag_test(bm, f, HULL_FLAG_HOLE)) {
BM_ITER_ELEM (e, &iter, f, BM_EDGES_OF_FACE) {
- if (BM_edge_face_count(e) == 1) {
+ if (BM_edge_is_boundary(e)) {
BMO_elem_flag_disable(bm, f, HULL_FLAG_HOLE);
break;
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index f6b9b18d716..b2f6761b1bc 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -165,7 +165,7 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar
}
/* apply the new difference to the rest of the shape keys,
- * note that this doent take rotations into account, we _could_ support
+ * note that this dosn't take rotations into account, we _could_ support
* this by getting the normals and coords for each shape key and
* re-calculate the smooth value for each but this is quite involved.
* for now its ok to simply apply the difference IMHO - campbell */
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c
index a428405fb8b..5d4698a0c7a 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -617,7 +617,7 @@ static void symm_kill_unused(Symm *symm)
!symmetric)
{
/* The edge might be used by a face outside the input set */
- if (BM_edge_face_count(e) == 0)
+ if (BM_edge_is_wire(e))
BM_edge_kill(symm->bm, e);
}
}
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index 374f6385ea7..44e74e320cc 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -844,7 +844,7 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a
* This function returns the aspet ration from the Collada camera.
*
* Note:COLLADA allows to specify either XFov, or YFov alone.
- * In tghat case the aspect ratio can be determined from
+ * In that case the aspect ratio can be determined from
* the viewport aspect ratio (which is 1:1 ?)
* XXX: check this: its probably wrong!
* If both values are specified, then the aspect ration is simply xfov/yfov
diff --git a/source/blender/compositor/operations/COM_PixelateOperation.h b/source/blender/compositor/operations/COM_PixelateOperation.h
index b16b21b2ec1..83603a59331 100644
--- a/source/blender/compositor/operations/COM_PixelateOperation.h
+++ b/source/blender/compositor/operations/COM_PixelateOperation.h
@@ -35,7 +35,7 @@
class PixelateOperation : public NodeOperation {
private:
/**
- * @brief cached refeerence to the input operation
+ * @brief cached reference to the input operation
*/
SocketReader *m_inputOperation;
public:
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 1defcf65ae8..e9ca7392752 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -139,11 +139,11 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
return &sseq->gpd;
}
break;
-
+
case SPACE_IMAGE: /* Image/UV Editor */
{
SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C);
-
+
/* for now, Grease Pencil data is associated with the space... */
/* XXX our convention for everything else is to link to data though... */
if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr);
@@ -159,19 +159,19 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
if (clip) {
if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
-
+
if (!track)
return NULL;
-
+
if (ptr)
RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr);
-
+
return &track->gpd;
}
else {
if (ptr)
RNA_id_pointer_create(&clip->id, ptr);
-
+
return &clip->gpd;
}
}
@@ -471,7 +471,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
mvalf[1] = (float)pt->y / 100.0f * ar->winy;
}
}
-
+
/* convert screen coordinate to 3d coordinates
* - method taken from editview.c - mouse_cursor()
*/
@@ -504,19 +504,22 @@ typedef struct tGpTimingData {
double inittime;
} tGpTimingData;
+/* init point buffers for timing data */
static void _gp_timing_data_set_nbr(tGpTimingData *gtd, int nbr)
{
float *tmp;
BLI_assert(nbr > gtd->num_points);
-
+
+ /* distances */
tmp = gtd->dists;
gtd->dists = MEM_callocN(sizeof(float) * nbr, __func__);
if (tmp) {
memcpy(gtd->dists, tmp, sizeof(float) * gtd->num_points);
MEM_freeN(tmp);
}
-
+
+ /* times */
tmp = gtd->times;
gtd->times = MEM_callocN(sizeof(float) * nbr, __func__);
if (tmp) {
@@ -527,20 +530,28 @@ static void _gp_timing_data_set_nbr(tGpTimingData *gtd, int nbr)
gtd->num_points = nbr;
}
+/* add stroke point to timing buffers */
static void gp_timing_data_add_point(tGpTimingData *gtd, double stroke_inittime, float time, float delta_dist)
{
if (time < 0.0f) {
/* This is a gap, negative value! */
- gtd->tot_time = -(gtd->times[gtd->cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time));
+ gtd->times[gtd->cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time);
+ gtd->tot_time = -gtd->times[gtd->cur_point];
+
gtd->gap_tot_time += gtd->times[gtd->cur_point] - gtd->times[gtd->cur_point - 1];
}
- else
- gtd->tot_time = (gtd->times[gtd->cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time));
- gtd->dists[gtd->cur_point] = (gtd->tot_dist += delta_dist);
+ else {
+ gtd->times[gtd->cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time);
+ gtd->tot_time = (gtd->times[gtd->cur_point]);
+ }
+
+ gtd->tot_dist += delta_dist;
+ gtd->dists[gtd->cur_point] = gtd->tot_dist;
+
gtd->cur_point++;
}
-/* In frames! Binary search for FCurve keys have a threshold of 0.01, so we can’t set
+/* In frames! Binary search for FCurve keys have a threshold of 0.01, so we can't set
* arbitrarily close points - this is esp. important with NoGaps mode!
*/
#define MIN_TIME_DELTA 0.02f
@@ -550,7 +561,7 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, int idx, int nbr_gaps,
float tot_gaps_time, float delta_time, float *next_delta_time)
{
int j;
-
+
for (j = idx + 1; j < gtd->num_points; j++) {
if (gtd->times[j] < 0) {
gtd->times[j] = -gtd->times[j];
@@ -562,20 +573,23 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, int idx, int nbr_gaps,
/* We want gaps that are in gtd->gap_duration +/- gtd->gap_randomness range,
* and which sum to exactly tot_gaps_time...
*/
- int rem_gaps = nbr_gaps - *nbr_done_gaps;
+ int rem_gaps = nbr_gaps - (*nbr_done_gaps);
if (rem_gaps < 2) {
/* Last gap, just give remaining time! */
*next_delta_time = tot_gaps_time;
}
else {
float delta, min, max;
+
/* This code ensures that if the first gaps have been shorter than average gap_duration,
* next gaps will tend to be longer (i.e. try to recover the lateness), and vice-versa!
*/
- delta = delta_time - (gtd->gap_duration * *nbr_done_gaps);
+ delta = delta_time - (gtd->gap_duration * (*nbr_done_gaps));
+
/* Clamp min between [-gap_randomness, 0.0], with lower delta giving higher min */
min = -gtd->gap_randomness - delta;
CLAMP(min, -gtd->gap_randomness, 0.0f);
+
/* Clamp max between [0.0, gap_randomness], with lower delta giving higher max */
max = gtd->gap_randomness - delta;
CLAMP(max, 0.0f, gtd->gap_randomness);
@@ -655,11 +669,11 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR
/* This one should *never* be negative! */
end_stroke_time = time_start + ((gtd->times[end_stroke_idx] + delta_time) / gtd->tot_time * time_range);
}
-
+
/* Simple proportional stuff... */
cu->ctime = gtd->dists[i] / gtd->tot_dist * cu->pathlen;
cfra = time_start + ((gtd->times[i] + delta_time) / gtd->tot_time * time_range);
-
+
/* And now, the checks about timing... */
if (i == start_stroke_idx) {
/* If first point of a stroke, be sure it's enough ahead of last valid keyframe, and
@@ -709,45 +723,44 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
FCurve *fcu;
PointerRNA ptr;
PropertyRNA *prop = NULL;
-
int nbr_gaps = 0, i;
-
+
if (gtd->mode == GP_STROKECONVERT_TIMING_NONE)
return;
-
+
/* gap_duration and gap_randomness are in frames, but we need seconds!!! */
gtd->gap_duration = FRA2TIME(gtd->gap_duration);
gtd->gap_randomness = FRA2TIME(gtd->gap_randomness);
-
+
/* Enable path! */
cu->flag |= CU_PATH;
cu->pathlen = gtd->frame_range;
-
- /* Get or create default action to add F-Curve+keyframe to */
- act = verify_adt_action((ID*)cu, TRUE);
- /* Create RNA stuff */
- RNA_id_pointer_create((ID*)cu, &ptr);
+
+ /* Get RNA pointer to read/write path time values */
+ RNA_id_pointer_create((ID *)cu, &ptr);
prop = RNA_struct_find_property(&ptr, "eval_time");
- /* Get or create fcurve */
+
+ /* Ensure we have an F-Curve to add keyframes to */
+ act = verify_adt_action((ID *)cu, TRUE);
fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, TRUE);
-
+
if (G.debug & G_DEBUG) {
printf("%s: tot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
for (i = 0; i < gtd->num_points; i++) {
printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]);
}
}
-
+
if (gtd->mode == GP_STROKECONVERT_TIMING_LINEAR) {
float cfra;
-
+
/* Linear extrapolation! */
fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
-
+
cu->ctime = 0.0f;
cfra = (float)gtd->start_frame;
insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
-
+
cu->ctime = cu->pathlen;
if (gtd->realtime) {
cfra += (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
@@ -760,34 +773,33 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
else {
/* Use actual recorded timing! */
float time_range;
-
+
/* CustomGaps specific */
float tot_gaps_time = 0.0f;
-
- /* Pre-process gaps, in case we don't want to keep their org timing */
+
+ /* Pre-process gaps, in case we don't want to keep their original timing */
if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
gp_stroke_path_animation_preprocess_gaps(gtd, &nbr_gaps, &tot_gaps_time);
}
-
+
if (gtd->realtime) {
time_range = (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
}
else {
time_range = (float)(gtd->end_frame - gtd->start_frame);
}
-
+
if (G.debug & G_DEBUG) {
- printf("Starting keying!\n");
+ printf("GP Stroke Path Conversion: Starting keying!\n");
}
-
+
gp_stroke_path_animation_add_keyframes(reports, ptr, prop, fcu, cu, gtd, time_range,
nbr_gaps, tot_gaps_time);
-
}
-
+
/* As we used INSERTKEY_FAST mode, we need to recompute all curve's handles now */
calchandles_fcurve(fcu);
-
+
if (G.debug & G_DEBUG) {
printf("%s: \ntot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
for (i = 0; i < gtd->num_points; i++) {
@@ -795,11 +807,11 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
}
printf("\n\n");
}
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
/* send updates */
- DAG_id_tag_update((ID*)cu, 0);
+ DAG_id_tag_update(&cu->id, 0);
}
#undef MIN_TIME_DELTA
@@ -813,14 +825,15 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
float minmax_weights[2], float rad_fac, int stitch, tGpTimingData *gtd)
{
bGPDspoint *pt;
- Nurb *nu = curnu ? *curnu : NULL;
+ Nurb *nu = (curnu) ? *curnu : NULL;
BPoint *bp, *prev_bp = NULL;
- int i, old_nbp = 0;
const int do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
+ int i, old_nbp = 0;
/* create new 'nurb' or extend current one within the curve */
if (nu) {
old_nbp = nu->pntsu;
+
/* If stitch, the first point of this stroke is already present in current nu.
* Else, we have to add to additional points to make the zero-radius link between strokes.
*/
@@ -837,9 +850,9 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
nu->resolu = cu->resolu;
nu->resolv = cu->resolv;
nu->knotsu = NULL;
-
+
nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * nu->pntsu, "bpoints");
-
+
stitch = FALSE; /* Security! */
}
@@ -861,11 +874,12 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
float delta_time;
prev_bp = NULL;
- if (old_nbp > 1 && gps->prev && gps->prev->totpoints > 1) {
+ if ((old_nbp > 1) && gps->prev && (gps->prev->totpoints > 1)) {
/* Only use last curve segment if previous stroke was not a single-point one! */
prev_bp = nu->bp + old_nbp - 2;
}
bp = nu->bp + old_nbp - 1;
+
/* XXX We do this twice... Not sure it's worth to bother about this! */
gp_strokepoint_convertcoords(C, gps, gps->points, p, subrect);
if (prev_bp) {
@@ -874,6 +888,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
else {
interp_v3_v3v3(p1, bp->vec, p, GAP_DFAC);
}
+
if (gps->totpoints > 1) {
/* XXX We do this twice... Not sure it's worth to bother about this! */
gp_strokepoint_convertcoords(C, gps, gps->points + 1, next_p, subrect);
@@ -882,7 +897,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
else {
interp_v3_v3v3(p2, p, bp->vec, GAP_DFAC);
}
-
+
/* First point */
bp++;
copy_v3_v3(bp->vec, p1);
@@ -898,7 +913,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
}
gp_timing_data_add_point(gtd, gtd->inittime, delta_time, len_v3v3((bp - 1)->vec, p1));
}
-
+
/* Second point */
bp++;
copy_v3_v3(bp->vec, p2);
@@ -915,25 +930,26 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
}
gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
}
-
+
old_nbp += 2;
}
if (old_nbp && do_gtd) {
prev_bp = nu->bp + old_nbp - 1;
}
+
/* add points */
- for (i = stitch ? 1 : 0, pt = gps->points + (stitch ? 1 : 0), bp = nu->bp + old_nbp;
+ for (i = (stitch) ? 1 : 0, pt = gps->points + ((stitch) ? 1 : 0), bp = nu->bp + old_nbp;
i < gps->totpoints;
i++, pt++, bp++)
{
float p3d[3];
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
-
+
/* get coordinates to add at */
gp_strokepoint_convertcoords(C, gps, pt, p3d, subrect);
copy_v3_v3(bp->vec, p3d);
bp->vec[3] = 1.0f;
-
+
/* set settings */
bp->f1 = SELECT;
bp->radius = width * rad_fac;
@@ -945,14 +961,14 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
else if (bp->weight > minmax_weights[1]) {
minmax_weights[1] = bp->weight;
}
-
+
/* Update timing data */
if (do_gtd) {
- gp_timing_data_add_point(gtd, gps->inittime, pt->time, prev_bp ? len_v3v3(prev_bp->vec, p3d) : 0.0f);
+ gp_timing_data_add_point(gtd, gps->inittime, pt->time, (prev_bp) ? len_v3v3(prev_bp->vec, p3d) : 0.0f);
}
prev_bp = bp;
}
-
+
/* add nurb to curve */
if (!curnu || !*curnu) {
BLI_addtail(&cu->nurb, nu);
@@ -960,7 +976,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
if (curnu) {
*curnu = nu;
}
-
+
BKE_nurb_knot_calc_u(nu);
}
@@ -968,7 +984,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
{
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
-
+
if (v3d) {
RegionView3D *rv3d = ar->regiondata;
@@ -979,7 +995,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
return 1;
}
}
-
+
return 0;
}
@@ -988,12 +1004,12 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
float minmax_weights[2], float rad_fac, int stitch, tGpTimingData *gtd)
{
bGPDspoint *pt;
- Nurb *nu = curnu ? *curnu : NULL;
+ Nurb *nu = (curnu) ? *curnu : NULL;
BezTriple *bezt, *prev_bezt = NULL;
int i, tot, old_nbezt = 0;
float p3d_cur[3], p3d_prev[3], p3d_next[3];
const int do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
-
+
/* create new 'nurb' or extend current one within the curve */
if (nu) {
old_nbezt = nu->pntsu;
@@ -1001,17 +1017,17 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
* so no need to add it.
* If no stitch, we want to add two additional points to make a "zero-radius" link between both strokes.
*/
- BKE_nurb_bezierPoints_add(nu, gps->totpoints + (stitch ? -1 : 2));
+ BKE_nurb_bezierPoints_add(nu, gps->totpoints + ((stitch) ? -1 : 2));
}
else {
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
-
+
nu->pntsu = gps->totpoints;
nu->resolu = 12;
nu->resolv = 12;
nu->type = CU_BEZIER;
nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints * sizeof(BezTriple), "bezts");
-
+
stitch = FALSE; /* Security! */
}
@@ -1024,9 +1040,9 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
/* get initial coordinates */
pt = gps->points;
if (tot) {
- gp_strokepoint_convertcoords(C, gps, pt, stitch ? p3d_prev : p3d_cur, subrect);
+ gp_strokepoint_convertcoords(C, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
if (tot > 1) {
- gp_strokepoint_convertcoords(C, gps, pt + 1, stitch ? p3d_cur : p3d_next, subrect);
+ gp_strokepoint_convertcoords(C, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
}
if (stitch && tot > 2) {
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
@@ -1035,7 +1051,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
/* If needed, make the link between both strokes with two zero-radius additional points */
if (curnu && old_nbezt) {
- /* Update last point's second handle! */
+ /* Update last point's second handle */
if (stitch) {
float h2[3];
bezt = nu->bezt + old_nbezt - 1;
@@ -1043,6 +1059,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
copy_v3_v3(bezt->vec[2], h2);
pt++;
}
+
/* Create "link points" */
/* About "zero-radius" point interpolations:
* - If we have at least two points in current curve (most common case), we linearly extrapolate
@@ -1055,7 +1072,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else {
float h1[3], h2[3], p1[3], p2[3];
float delta_time;
-
+
prev_bezt = NULL;
if (old_nbezt > 1 && gps->prev && gps->prev->totpoints > 1) {
/* Only use last curve segment if previous stroke was not a single-point one! */
@@ -1074,15 +1091,15 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else {
interp_v3_v3v3(p2, p3d_cur, bezt->vec[1], GAP_DFAC);
}
-
+
/* Second handle of last point */
interp_v3_v3v3(h2, bezt->vec[1], p1, BEZT_HANDLE_FAC);
copy_v3_v3(bezt->vec[2], h2);
-
+
/* First point */
interp_v3_v3v3(h1, p1, bezt->vec[1], BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p1, p2, BEZT_HANDLE_FAC);
-
+
bezt++;
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p1);
@@ -1090,7 +1107,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
minmax_weights[0] = bezt->radius = bezt->weight = 0.0f;
-
+
if (do_gtd) {
if (prev_bezt) {
delta_time = gtd->tot_time + (gtd->tot_time - gtd->times[gtd->cur_point - 1]) * GAP_DFAC;
@@ -1100,11 +1117,11 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
}
gp_timing_data_add_point(gtd, gtd->inittime, delta_time, len_v3v3((bezt - 1)->vec[1], p1));
}
-
+
/* Second point */
interp_v3_v3v3(h1, p2, p1, BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p2, p3d_cur, BEZT_HANDLE_FAC);
-
+
bezt++;
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p2);
@@ -1112,7 +1129,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
minmax_weights[0] = bezt->radius = bezt->weight = 0.0f;
-
+
if (do_gtd) {
/* This negative delta_time marks the gap! */
if (tot > 1) {
@@ -1123,7 +1140,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
}
gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
}
-
+
old_nbezt += 2;
copy_v3_v3(p3d_prev, p2);
}
@@ -1131,29 +1148,30 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
if (old_nbezt && do_gtd) {
prev_bezt = nu->bezt + old_nbezt - 1;
}
+
/* add points */
for (i = stitch ? 1 : 0, bezt = nu->bezt + old_nbezt; i < tot; i++, pt++, bezt++) {
float h1[3], h2[3];
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
-
+
if (i || old_nbezt) {
interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC);
}
else {
interp_v3_v3v3(h1, p3d_cur, p3d_next, -BEZT_HANDLE_FAC);
}
-
+
if (i < tot - 1) {
interp_v3_v3v3(h2, p3d_cur, p3d_next, BEZT_HANDLE_FAC);
}
else {
interp_v3_v3v3(h2, p3d_cur, p3d_prev, -BEZT_HANDLE_FAC);
}
-
+
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p3d_cur);
copy_v3_v3(bezt->vec[2], h2);
-
+
/* set settings */
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
@@ -1166,23 +1184,23 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else if (bezt->weight > minmax_weights[1]) {
minmax_weights[1] = bezt->weight;
}
-
+
/* Update timing data */
if (do_gtd) {
gp_timing_data_add_point(gtd, gps->inittime, pt->time, prev_bezt ? len_v3v3(prev_bezt->vec[1], p3d_cur) : 0.0f);
}
-
+
/* shift coord vects */
copy_v3_v3(p3d_prev, p3d_cur);
copy_v3_v3(p3d_cur, p3d_next);
-
+
if (i + 2 < tot) {
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
}
-
+
prev_bezt = bezt;
}
-
+
/* must calculate handles or else we crash */
BKE_nurb_handles_calc(nu);
@@ -1200,6 +1218,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
static void gp_stroke_finalize_curve_endpoints(Curve *cu)
{
+ /* start */
Nurb *nu = cu->nurb.first;
int i = 0;
if (nu->bezt) {
@@ -1214,7 +1233,8 @@ static void gp_stroke_finalize_curve_endpoints(Curve *cu)
bp[i].weight = bp[i].radius = 0.0f;
}
}
-
+
+ /* end */
nu = cu->nurb.last;
i = nu->pntsu - 1;
if (nu->bezt) {
@@ -1237,7 +1257,7 @@ static void gp_stroke_norm_curve_weights(Curve *cu, float minmax_weights[2])
const float delta = minmax_weights[0];
const float fac = 1.0f / (minmax_weights[1] - delta);
int i;
-
+
for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
@@ -1269,11 +1289,11 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
/* camera framing */
rctf subrect, *subrect_ptr = NULL;
-
+
/* error checking */
if (ELEM3(NULL, gpd, gpl, gpf))
return;
-
+
/* only convert if there are any strokes on this layer's frame to convert */
if (gpf->strokes.first == NULL)
return;
@@ -1282,7 +1302,7 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
if (gp_camera_view_subrect(C, &subrect)) {
subrect_ptr = &subrect;
}
-
+
/* init the curve object (remove rotation and get curve data from it)
* - must clear transforms set on object, as those skew our results
*/
@@ -1291,28 +1311,34 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
zero_v3(ob->rot);
cu = ob->data;
cu->flag |= CU_3D;
-
+
/* rename object and curve to layer name */
rename_id((ID *)ob, gpl->info);
rename_id((ID *)cu, gpl->info);
-
- gtd->inittime = ((bGPDstroke*)gpf->strokes.first)->inittime;
-
+
+ gtd->inittime = ((bGPDstroke *)gpf->strokes.first)->inittime;
+
/* add points to curve */
for (gps = gpf->strokes.first; gps; gps = gps->next) {
/* Detect new strokes created because of GP_STROKE_BUFFER_MAX reached,
* and stitch them to previous one.
*/
int stitch = FALSE;
+
if (prev_gps) {
bGPDspoint *pt1 = prev_gps->points + prev_gps->totpoints - 1;
bGPDspoint *pt2 = gps->points;
- if (pt1->x == pt2->x && pt1->y == pt2->y)
+
+ if ((pt1->x == pt2->x) && (pt1->y == pt2->y)) {
stitch = TRUE;
+ }
}
+
/* Decide whether we connect this stroke to previous one */
- if (!(stitch || link_strokes))
+ if (!(stitch || link_strokes)) {
nu = NULL;
+ }
+
switch (mode) {
case GP_STROKECONVERT_PATH:
gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, gtd);
@@ -1332,20 +1358,25 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
gp_stroke_finalize_curve_endpoints(cu);
/* Update curve's weights, if needed */
- if (norm_weights && (minmax_weights[0] > 0.0f || minmax_weights[1] < 1.0f))
+ if (norm_weights && ((minmax_weights[0] > 0.0f) || (minmax_weights[1] < 1.0f)))
gp_stroke_norm_curve_weights(cu, minmax_weights);
/* Create the path animation, if needed */
gp_stroke_path_animation(C, reports, cu, gtd);
- /* Reset org object as active, else we can't edit operator's settings!!! */
+ /* Reset original object as active, else we can't edit operator's settings!!! */
/* set layers OK */
newbase = BASACT;
- newbase->lay = base->lay;
- ob->lay = newbase->lay;
+ if (base) {
+ newbase->lay = base->lay;
+ ob->lay = newbase->lay;
+ }
+
/* restore, BKE_object_add sets active */
BASACT = base;
- base->flag |= SELECT;
+ if (base) {
+ base->flag |= SELECT;
+ }
}
/* --- */
@@ -1361,13 +1392,14 @@ static int gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOper
bGPDspoint *pt;
double base_time, cur_time, prev_time = -1.0;
int i, valid = TRUE;
-
+
do {
base_time = cur_time = gps->inittime;
if (cur_time <= prev_time) {
valid = FALSE;
break;
}
+
prev_time = cur_time;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
cur_time = base_time + (double)pt->time;
@@ -1380,11 +1412,12 @@ static int gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOper
}
prev_time = cur_time;
}
+
if (!valid) {
break;
}
} while ((gps = gps->next));
-
+
if (op) {
RNA_boolean_set(op->ptr, "use_timing_data", valid);
}
@@ -1396,6 +1429,7 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UN
{
int start_frame = RNA_int_get(ptr, "start_frame");
int end_frame = RNA_int_get(ptr, "end_frame");
+
if (end_frame <= start_frame) {
RNA_int_set(ptr, "end_frame", start_frame + 1);
}
@@ -1423,19 +1457,19 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
int link_strokes = RNA_boolean_get(op->ptr, "use_link_strokes");
int valid_timing;
tGpTimingData gtd;
-
+
/* check if there's data to work with */
if (gpd == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No grease pencil data to work on");
+ BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data to work on");
return OPERATOR_CANCELLED;
}
-
+
if (!RNA_property_is_set(op->ptr, prop) && !gp_convert_check_has_valid_timing(C, gpl, op)) {
BKE_report(op->reports, RPT_WARNING,
- "Current grease pencil strokes have no valid timing data, most timing options will be hidden!");
+ "Current Grease Pencil strokes have no valid timing data, most timing options will be hidden!");
}
valid_timing = RNA_property_boolean_get(op->ptr, prop);
-
+
gtd.mode = RNA_enum_get(op->ptr, "timing_mode");
/* Check for illegal timing mode! */
if (!valid_timing && !ELEM(gtd.mode, GP_STROKECONVERT_TIMING_NONE, GP_STROKECONVERT_TIMING_LINEAR)) {
@@ -1445,7 +1479,8 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
if (!link_strokes) {
gtd.mode = GP_STROKECONVERT_TIMING_NONE;
}
-
+
+ /* grab all relevant settings */
gtd.frame_range = RNA_int_get(op->ptr, "frame_range");
gtd.start_frame = RNA_int_get(op->ptr, "start_frame");
gtd.realtime = valid_timing ? RNA_boolean_get(op->ptr, "use_realtime") : FALSE;
@@ -1458,13 +1493,24 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
gtd.dists = gtd.times = NULL;
gtd.tot_dist = gtd.tot_time = gtd.gap_tot_time = 0.0f;
gtd.inittime = 0.0;
-
+
+ /* perform conversion */
gp_layer_to_curve(C, op->reports, gpd, gpl, mode, norm_weights, rad_fac, link_strokes, &gtd);
-
+
+ /* free temp memory */
+ if (gtd.dists) {
+ MEM_freeN(gtd.dists);
+ gtd.dists = NULL;
+ }
+ if (gtd.times) {
+ MEM_freeN(gtd.times);
+ gtd.times = NULL;
+ }
+
/* notifiers */
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1478,7 +1524,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
float gap_duration = RNA_float_get(ptr, "gap_duration");
float gap_randomness = RNA_float_get(ptr, "gap_randomness");
int valid_timing = RNA_boolean_get(ptr, "use_timing_data");
-
+
/* Always show those props */
if (strcmp(prop_id, "type") == 0 ||
strcmp(prop_id, "use_normalize_weights") == 0 ||
@@ -1487,7 +1533,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
{
return TRUE;
}
-
+
/* Never show this prop */
if (strcmp(prop_id, "use_timing_data") == 0)
return FALSE;
@@ -1496,7 +1542,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
/* Only show when link_stroke is TRUE */
if (strcmp(prop_id, "timing_mode") == 0)
return TRUE;
-
+
if (timing_mode != GP_STROKECONVERT_TIMING_NONE) {
/* Only show when link_stroke is TRUE and stroke timing is enabled */
if (strcmp(prop_id, "frame_range") == 0 ||
@@ -1504,26 +1550,26 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
{
return TRUE;
}
-
+
/* Only show if we have valid timing data! */
if (valid_timing && strcmp(prop_id, "use_realtime") == 0)
return TRUE;
-
+
/* Only show if realtime or valid_timing is FALSE! */
if ((!realtime || !valid_timing) && strcmp(prop_id, "end_frame") == 0)
return TRUE;
-
+
if (valid_timing && timing_mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
/* Only show for custom gaps! */
if (strcmp(prop_id, "gap_duration") == 0)
return TRUE;
-
+
/* Only show randomness for non-null custom gaps! */
- if (strcmp(prop_id, "gap_randomness") == 0 && gap_duration > 0.0f)
+ if (strcmp(prop_id, "gap_randomness") == 0 && (gap_duration > 0.0f))
return TRUE;
-
+
/* Only show seed for randomize action! */
- if (strcmp(prop_id, "seed") == 0 && gap_duration > 0.0f && gap_randomness > 0.0f)
+ if (strcmp(prop_id, "seed") == 0 && (gap_duration > 0.0f) && (gap_randomness > 0.0f))
return TRUE;
}
}
@@ -1565,15 +1611,18 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", "Which type of curve to convert to");
+
RNA_def_boolean(ot->srna, "use_normalize_weights", TRUE, "Normalize Weight",
"Normalize weight (set from stroke width)");
RNA_def_float(ot->srna, "radius_multiplier", 1.0f, 0.0f, 1000.0f, "Radius Fac",
"Multiplier for the points' radii (set from stroke width)", 0.0f, 10.0f);
RNA_def_boolean(ot->srna, "use_link_strokes", TRUE, "Link Strokes",
"Whether to link strokes with zero-radius sections of curves");
+
prop = RNA_def_enum(ot->srna, "timing_mode", prop_gpencil_convert_timingmodes, GP_STROKECONVERT_TIMING_FULL,
"Timing Mode", "How to use timing data stored in strokes");
RNA_def_enum_funcs(prop, rna_GPConvert_mode_items);
+
RNA_def_int(ot->srna, "frame_range", 100, 1, 10000, "Frame Range",
"The duration of evaluation of the path control curve", 1, 1000);
RNA_def_int(ot->srna, "start_frame", 1, 1, 100000, "Start Frame",
@@ -1583,16 +1632,18 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
prop = RNA_def_int(ot->srna, "end_frame", 250, 1, 100000, "End Frame",
"The end frame of the path control curve (if Realtime is not set)", 1, 100000);
RNA_def_property_update_runtime(prop, gp_convert_set_end_frame);
+
RNA_def_float(ot->srna, "gap_duration", 0.0f, 0.0f, 10000.0f, "Gap Duration",
"Custom Gap mode: (Average) length of gaps, in frames "
- "(note: realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
+ "(Note: Realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
RNA_def_float(ot->srna, "gap_randomness", 0.0f, 0.0f, 10000.0f, "Gap Randomness",
"Custom Gap mode: Number of frames that gap lengths can vary", 0.0f, 1000.0f);
RNA_def_int(ot->srna, "seed", 0, 0, 1000, "Random Seed",
"Custom Gap mode: Random generator seed", 0, 100);
+
/* Note: Internal use, this one will always be hidden by UI code... */
prop = RNA_def_boolean(ot->srna, "use_timing_data", FALSE, "Has Valid Timing",
- "Whether the converted grease pencil layer has valid timing data (internal use)");
+ "Whether the converted Grease Pencil layer has valid timing data (internal use)");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index fcead283033..77f6d2bda5c 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -100,8 +100,8 @@ typedef struct tGPsdata {
short radius; /* radius of influence for eraser */
short flags; /* flags that can get set during runtime */
-
- /* Those needs to be doubles, as (at least under unix) they are in seconds since epoch,
+
+ /* These need to be doubles, as (at least under unix) they are in seconds since epoch,
* float (and its 7 digits precision) is definitively not enough here!
* double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least.
*/
@@ -110,7 +110,7 @@ typedef struct tGPsdata {
double ocurtime; /* Used when converting to path */
float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space
- * to region space */
+ * to region space */
float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */
@@ -455,11 +455,13 @@ static void gp_stroke_smooth(tGPsdata *p)
if ((cmx <= 2) || (gpd->sbuffer == NULL))
return;
- /* Calculate smoothing coordinates using weighted-averages */
- /* XXX DO NOT smooth first and last points! */
+ /* Calculate smoothing coordinates using weighted-averages
+ * WARNING: we do NOT smooth first and last points (to avoid shrinkage)
+ */
spt = (tGPspoint *)gpd->sbuffer;
- /* This small array stores the last two points' org coordinates, we don't want to use already averaged ones!
- * Note it is used as a cyclic buffer...
+
+ /* This (tmp_spt) small array stores the last two points' original coordinates,
+ * as we don't want to use already averaged ones! It is used as a cyclic buffer...
*/
tmp_spt[0] = *spt;
for (i = 1, spt++; i < cmx - 1; i++, spt++) {
@@ -469,7 +471,7 @@ static void gp_stroke_smooth(tGPsdata *p)
const tGPspoint *pd = pc + 1;
const tGPspoint *pe = (i + 2 < cmx) ? (pc + 2) : (pd);
- /* Store current point's org state for the two next points! */
+ /* Store current point's original state for the two next points! */
tmp_spt[i % 3] = *spt;
spt->x = (int)(0.1 * pa->x + 0.2 * pb->x + 0.4 * pc->x + 0.2 * pd->x + 0.1 * pe->x);
@@ -588,7 +590,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
return;
}
}
-
+
/* allocate memory for a new stroke */
gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
@@ -600,10 +602,10 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* allocate enough memory for a continuous array for storage points */
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
-
+
/* set pointer to first non-initialized point */
pt = gps->points + (gps->totpoints - totelem);
-
+
/* copy points from the buffer to the stroke */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only -> only endpoints */
@@ -722,7 +724,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
if (depth_arr)
MEM_freeN(depth_arr);
}
-
+
/* add stroke to frame */
BLI_addtail(&p->gpf->strokes, gps);
gp_stroke_added_enable(p);
@@ -735,7 +737,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
{
bGPDspoint *pt_tmp = gps->points;
bGPDstroke *gsn = NULL;
-
+
/* if stroke only had two points, get rid of stroke */
if (gps->totpoints == 2) {
/* free stroke points, then stroke */
@@ -745,7 +747,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* nothing left in stroke, so stop */
return 1;
}
-
+
/* if last segment, just remove segment from the stroke */
else if (i == gps->totpoints - 2) {
/* allocate new points array, and assign most of the old stroke there */
@@ -759,17 +761,17 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* nothing left in stroke, so stop */
return 1;
}
-
+
/* if first segment, just remove segment from the stroke */
else if (i == 0) {
/* allocate new points array, and assign most of the old stroke there */
gps->totpoints--;
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint) * gps->totpoints);
-
+
/* We must adjust timings!
* Each point's timing data is a delta from stroke's inittime, so as we erase the first
- * point of the stroke, we have to offset this inittime and all remaing points' delta values.
+ * point of the stroke, we have to offset this inittime and all remaining points' delta values.
* This way we get a new stroke with exactly the same timing as if user had started drawing from
* the second point...
*/
@@ -777,9 +779,9 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
bGPDspoint *pts;
float delta = pt_tmp[1].time;
int j;
-
- gps->inittime += delta;
-
+
+ gps->inittime += (double)delta;
+
pts = gps->points;
for (j = 0; j < gps->totpoints; j++, pts++) {
pts->time -= delta;
@@ -792,7 +794,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* no break here, as there might still be stuff to remove in this stroke */
return 0;
}
-
+
/* segment occurs in 'middle' of stroke, so split */
else {
/* duplicate stroke, and assign 'later' data to that stroke */
@@ -814,15 +816,15 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
bGPDspoint *pts;
float delta = pt_tmp[i].time;
int j;
-
- gsn->inittime += delta;
-
+
+ gsn->inittime += (double)delta;
+
pts = gsn->points;
for (j = 0; j < gsn->totpoints; j++, pts++) {
pts->time -= delta;
}
}
-
+
/* adjust existing stroke */
gps->totpoints = i;
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
@@ -844,7 +846,7 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv
const float mval_fl[2] = {mval[0], mval[1]};
const float screen_co_a[2] = {x0, y0};
const float screen_co_b[2] = {x1, y1};
-
+
if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
return TRUE;
}
@@ -904,7 +906,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0);
/* do boundbox check first */
-
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
/* only check if point is inside */
if (((x0 - mval[0]) * (x0 - mval[0]) + (y0 - mval[1]) * (y0 - mval[1])) <= rad * rad) {
@@ -922,10 +923,10 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
/* get points to work with */
pt1 = gps->points + i;
pt2 = gps->points + i + 1;
-
+
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0);
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1);
-
+
/* check that point segment of the boundbox of the eraser stroke */
if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) {
@@ -1033,7 +1034,7 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
}
}
break;
-
+
case SPACE_NODE:
{
/* SpaceNode *snode = curarea->spacedata.first; */
@@ -1554,14 +1555,14 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
PointerRNA itemptr;
float mousef[2];
int tablet = 0;
-
+
/* convert from window-space to area-space mouse coordinates
* NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding...
*/
p->mval[0] = event->mval[0] + 1;
p->mval[1] = event->mval[1] + 1;
p->curtime = PIL_check_seconds_timer();
-
+
/* handle pressure sensitivity (which is supplied by tablets) */
if (event->custom == EVT_DATA_TABLET) {
wmTabletData *wmtab = event->customdata;
@@ -1592,7 +1593,7 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
p->mvalo[1] = p->mval[1];
p->opressure = p->pressure;
p->inittime = p->ocurtime = p->curtime;
-
+
/* special exception here for too high pressure values on first touch in
* windows for some tablets, then we just skip first touch...
*/
@@ -1601,7 +1602,7 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
}
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
-
+
/* apply the current latest drawing point */
gpencil_draw_apply(op, p);
@@ -1754,7 +1755,7 @@ static int gpencil_area_exists(bContext *C, ScrArea *sa_test)
static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
{
tGPsdata *p = op->customdata;
-
+
/* we must check that we're still within the area that we're set up to work from
* otherwise we could crash (see bug #20586)
*/
@@ -1762,20 +1763,20 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
printf("\t\t\tGP - wrong area execution abort!\n");
p->status = GP_STATUS_ERROR;
}
-
+
/* printf("\t\tGP - start stroke\n"); */
-
+
/* we may need to set up paint env again if we're resuming */
/* XXX: watch it with the paintmode! in future,
* it'd be nice to allow changing paint-mode when in sketching-sessions */
/* XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support */
-
+
if (gp_session_initdata(C, p))
gp_paint_initstroke(p, p->paintmode);
-
+
if (p->status != GP_STATUS_ERROR)
p->status = GP_STATUS_PAINTING;
-
+
return op->customdata;
}
@@ -1800,7 +1801,7 @@ static void gpencil_stroke_end(wmOperator *op)
static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
{
tGPsdata *p = op->customdata;
- int estate = OPERATOR_PASS_THROUGH; /* default exit state */
+ int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */
/* if (event->type == NDOF_MOTION)
* return OPERATOR_PASS_THROUGH;
@@ -1814,7 +1815,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
* better in tools that immediately apply
* in 3D space.
*/
-
+
/* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */
if (ISKEYBOARD(event->type))
estate = OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 5ffcfbd94f0..865da8f0e6e 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -153,6 +153,11 @@ int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short
void EDBM_selectmode_set(struct BMEditMesh *em);
void EDBM_selectmode_convert(struct BMEditMesh *em, const short selectmode_old, const short selectmode_new);
+/* user access this */
+int EDBM_selectmode_toggle(struct bContext *C, const short selectmode_new,
+ const int action, const int use_extend, const int use_expand);
+
+
void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const short select);
void EDBM_select_toggle_all(struct BMEditMesh *em);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 540a9cc752b..23d3810e058 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -358,7 +358,7 @@ struct uiBlock {
char color_profile; /* color profile for correcting linear colors for display */
- char *display_device; /* display devide name used to display this block,
+ char *display_device; /* display device name used to display this block,
* used by color widgets to transform colors from/to scene linear
*/
};
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 52d909a34c0..9eec7c195b2 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -68,6 +68,8 @@
#define EM_SEPR_X 6
#define EM_SEPR_Y 6
+// #define USE_OP_RESET_BUT // we may want to make this optional, disable for now.
+
#define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \
if (ot == NULL) { \
ui_item_disabled(layout, _opname); \
@@ -2840,10 +2842,12 @@ const char *uiLayoutIntrospect(uiLayout *layout)
return str;
}
+#ifdef USE_OP_RESET_BUT
static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt, void *UNUSED(arg_dummy2))
{
WM_operator_properties_reset((wmOperator *)op_pt);
}
+#endif
/* this function does not initialize the layout, functions can be called on the layout before and after */
void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
@@ -2911,6 +2915,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
}
}
+#ifdef USE_OP_RESET_BUT
/* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
* but this is not so important if this button is drawn in those cases
* (which isn't all that likely anyway) - campbell */
@@ -2925,6 +2930,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL);
}
+#endif
/* set various special settings for buttons */
{
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 68d85aab80f..dbb401c898b 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -867,7 +867,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA);
- if (modifier_sameTopology(md) && !modifier_nonGeometrical(md))
+ if (modifier_isSameTopology(md) && !modifier_isNonGeometrical(md))
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape Key"), 0, "apply_as", MODIFIER_APPLY_SHAPE);
}
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 70b359d3e28..b8736d4f1d0 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -420,7 +420,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
if (!view_aligned)
rot[0] += (float)M_PI / 2.0f;
- obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer);
+ obedit = make_prim_init(C, "Suzanne", &dia, mat, &state, loc, rot, layer);
mat[0][0] *= dia;
mat[1][1] *= dia;
mat[2][2] *= dia;
diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c
index 468d0d8d8c6..4324e50f914 100644
--- a/source/blender/editors/mesh/editmesh_bvh.c
+++ b/source/blender/editors/mesh/editmesh_bvh.c
@@ -157,13 +157,13 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit)
if (flag & BMBVH_RESPECT_SELECT) {
- /* note, the arrays wont allign now! take care */
+ /* note, the arrays wont align now! take care */
if (!BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_SELECT)) {
continue;
}
}
else if (flag & BMBVH_RESPECT_HIDDEN) {
- /* note, the arrays wont allign now! take care */
+ /* note, the arrays wont align now! take care */
if (BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_HIDDEN)) {
continue;
}
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 82447cc0168..5ba85115b2f 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -2573,8 +2573,8 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
int nco = BLI_countlist(chain) - 1;
float (*cos)[3] = NULL;
KnifeVert **kverts;
- BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, nco, __func__);
- BLI_array_fixedstack_declare(kverts, BM_NGON_STACK_SIZE, nco, __func__);
+ BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
+ BLI_array_fixedstack_declare(kverts, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
kfe = ((Ref *)chain->first)->ref;
v1 = kfe->v1->v ? kfe->v1->v : kfe->v2->v;
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index bf4ee0eb61f..f951073155d 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -307,7 +307,8 @@ static void ringsel_find_edge(RingSelOpData *lcd, int cuts)
static void ringsel_finish(bContext *C, wmOperator *op)
{
RingSelOpData *lcd = op->customdata;
- int cuts = RNA_int_get(op->ptr, "number_cuts");
+ const int cuts = RNA_int_get(op->ptr, "number_cuts");
+ const float smoothness = 0.292f * RNA_float_get(op->ptr, "smoothness");
if (lcd->eed) {
BMEditMesh *em = lcd->em;
@@ -319,7 +320,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
* Note though that it will break edgeslide in this specific case.
* See [#31939]. */
BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
- 0.0f, 0.0f, 0.0f,
+ smoothness, 0.0f, 0.0f,
cuts,
SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, 0);
@@ -413,6 +414,7 @@ static int ringcut_cancel(bContext *C, wmOperator *op)
static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
+ ScrArea *sa = CTX_wm_area(C);
Object *obedit = CTX_data_edit_object(C);
RingSelOpData *lcd;
BMEdge *edge;
@@ -438,13 +440,17 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
lcd->eed = edge;
ringsel_find_edge(lcd, 1);
}
- ED_area_headerprint(CTX_wm_area(C), "Select a ring to be cut, use mouse-wheel or page-up/down for number of cuts");
+ ED_area_headerprint(sa,
+ "Select a ring to be cut, "
+ "use mouse-wheel or page-up/down for number of cuts, "
+ "Hold Alt for smooth");
return OPERATOR_RUNNING_MODAL;
}
static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
{
+ float smoothness = RNA_float_get(op->ptr, "smoothness");
int cuts = RNA_int_get(op->ptr, "number_cuts");
RingSelOpData *lcd = op->customdata;
int show_cuts = 0;
@@ -491,11 +497,17 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
case WHEELUPMOUSE: /* change number of cuts */
if (event->val == KM_RELEASE)
break;
-
- cuts++;
- RNA_int_set(op->ptr, "number_cuts", cuts);
- ringsel_find_edge(lcd, cuts);
- show_cuts = TRUE;
+ if (event->alt == 0) {
+ cuts++;
+ RNA_int_set(op->ptr, "number_cuts", cuts);
+ ringsel_find_edge(lcd, cuts);
+ show_cuts = TRUE;
+ }
+ else {
+ smoothness = min_ff(smoothness + 0.05f, 4.0f);
+ RNA_float_set(op->ptr, "smoothness", smoothness);
+ show_cuts = TRUE;
+ }
ED_region_tag_redraw(lcd->ar);
break;
@@ -505,10 +517,17 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_RELEASE)
break;
- cuts = max_ii(cuts - 1, 0);
- RNA_int_set(op->ptr, "number_cuts", cuts);
- ringsel_find_edge(lcd, cuts);
- show_cuts = TRUE;
+ if (event->alt == 0) {
+ cuts = max_ii(cuts - 1, 0);
+ RNA_int_set(op->ptr, "number_cuts", cuts);
+ ringsel_find_edge(lcd, cuts);
+ show_cuts = TRUE;
+ }
+ else {
+ smoothness = max_ff(smoothness - 0.05f, 0.0f);
+ RNA_float_set(op->ptr, "smoothness", smoothness);
+ show_cuts = TRUE;
+ }
ED_region_tag_redraw(lcd->ar);
break;
@@ -552,7 +571,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
if (show_cuts) {
char buf[64];
- BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d", cuts);
+ BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d, Smooth: %.2f (Alt)", cuts, smoothness);
ED_area_headerprint(CTX_wm_area(C), buf);
}
@@ -604,4 +623,7 @@ void MESH_OT_loopcut(wmOperatorType *ot)
prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
/* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor", 0.0f, 4.0f);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index c2f2e97b86a..8b217223907 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -56,6 +56,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
+#include "ED_util.h"
#include "ED_uvedit.h"
#include "ED_object.h"
#include "ED_view3d.h"
@@ -68,6 +69,7 @@
#include "mesh_intern.h"
+#include "UI_resources.h"
/* ****************************** MIRROR **************** */
@@ -917,6 +919,74 @@ void MESH_OT_select_similar(wmOperatorType *ot)
RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0);
}
+
+/* **************** Mode Select *************** */
+
+static int edbm_select_mode_exec(bContext *C, wmOperator *op)
+{
+ const int type = RNA_enum_get(op->ptr, "type");
+ const int action = RNA_enum_get(op->ptr, "action");
+ const int use_extend = RNA_boolean_get(op->ptr, "use_extend");
+ const int use_expand = RNA_boolean_get(op->ptr, "use_expand");
+
+ if (EDBM_selectmode_toggle(C, type, action, use_extend, use_expand)) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int edbm_select_mode_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ // RNA_enum_set(op->ptr, "type"); /* type must be set already */
+ RNA_boolean_set(op->ptr, "use_extend", event->shift);
+ RNA_boolean_set(op->ptr, "use_expand", event->ctrl);
+ return edbm_select_mode_exec(C, op);
+}
+
+void MESH_OT_select_mode(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem elem_items[] = {
+ {SCE_SELECT_VERTEX, "VERT", ICON_VERTEXSEL, "Vertices", ""},
+ {SCE_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edges", ""},
+ {SCE_SELECT_FACE, "FACE", ICON_FACESEL, "Faces", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static EnumPropertyItem actions_items[] = {
+ {0, "DISABLE", 0, "Disable", "Disable selected markers"},
+ {1, "ENABLE", 0, "Enable", "Enable selected markers"},
+ {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name = "Select Mode";
+ ot->idname = "MESH_OT_select_mode";
+ ot->description = "Change selection mode";
+
+ /* api callbacks */
+ ot->invoke = edbm_select_mode_invoke;
+ ot->exec = edbm_select_mode_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "use_extend", FALSE, "Extend", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "use_expand", FALSE, "Expand", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ ot->prop = prop = RNA_def_enum(ot->srna, "type", elem_items, 0, "Type", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ RNA_def_enum(ot->srna, "action", actions_items, 2, "Action", "Selection action to execute");
+}
+
/* ***************************************************** */
/* **************** LOOP SELECTS *************** */
@@ -1891,56 +1961,146 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s
BMFace *efa;
BMIter iter;
+ /* first tag-to-select, then select --- this avoids a feedback loop */
+
/* have to find out what the selectionmode was previously */
if (selectmode_old == SCE_SELECT_VERTEX) {
if (selectmode_new == SCE_SELECT_EDGE) {
- /* select all edges associated with every selected vertex */
- eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
- for (; eed; eed = BM_iter_step(&iter)) {
- if ((BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
- BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)))
- {
+ /* select all edges associated with every selected vert */
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_set(eed, BM_ELEM_TAG, BM_edge_is_any_vert_flag_test(eed, BM_ELEM_SELECT));
+ }
+
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
BM_edge_select_set(em->bm, eed, TRUE);
}
}
}
else if (selectmode_new == SCE_SELECT_FACE) {
- BMIter liter;
- BMLoop *l;
-
- /* select all faces associated with every selected vertex */
- efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
- for (; efa; efa = BM_iter_step(&iter)) {
- l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
- for (; l; l = BM_iter_step(&liter)) {
- if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
- BM_face_select_set(em->bm, efa, TRUE);
- break;
- }
+ /* select all faces associated with every selected vert */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_vert_flag_test(efa, BM_ELEM_SELECT));
+ }
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ BM_face_select_set(em->bm, efa, TRUE);
}
}
}
}
else if (selectmode_old == SCE_SELECT_EDGE) {
if (selectmode_new == SCE_SELECT_FACE) {
- BMIter liter;
- BMLoop *l;
-
- /* select all faces associated with every selected vertex */
- efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
- for (; efa; efa = BM_iter_step(&iter)) {
- l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
- for (; l; l = BM_iter_step(&liter)) {
- if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
- BM_face_select_set(em->bm, efa, TRUE);
- break;
- }
+ /* select all faces associated with every selected edge */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_edge_flag_test(efa, BM_ELEM_SELECT));
+ }
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ BM_face_select_set(em->bm, efa, TRUE);
}
}
}
}
}
+/* user facing function, does notification and undo push */
+int EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
+ const int action, const int use_extend, const int use_expand)
+{
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = NULL;
+ int ret = FALSE;
+
+ if (obedit && obedit->type == OB_MESH) {
+ em = BMEdit_FromObject(obedit);
+ }
+
+ if (em == NULL) {
+ return ret;
+ }
+
+ switch (action) {
+ case -1:
+ /* already set */
+ break;
+ case 0: /* disable */
+ /* check we have something to do */
+ if ((em->selectmode & selectmode_new) == 0) {
+ return FALSE;
+ }
+ em->selectmode &= ~selectmode_new;
+ break;
+ case 1: /* enable */
+ /* check we have something to do */
+ if ((em->selectmode & selectmode_new) != 0) {
+ return FALSE;
+ }
+ em->selectmode |= selectmode_new;
+ break;
+ case 2: /* toggle */
+ /* can't disable this flag if its the only one set */
+ if (em->selectmode == selectmode_new) {
+ return FALSE;
+ }
+ em->selectmode ^= selectmode_new;
+ break;
+ default:
+ BLI_assert(0);
+ }
+
+ switch (selectmode_new) {
+ case SCE_SELECT_VERTEX:
+ if (use_extend == 0 || em->selectmode == 0)
+ em->selectmode = SCE_SELECT_VERTEX;
+ ts->selectmode = em->selectmode;
+ EDBM_selectmode_set(em);
+ ret = TRUE;
+ break;
+ case SCE_SELECT_EDGE:
+ if (use_extend == 0 || em->selectmode == 0) {
+ if (use_expand) {
+ const short selmode_max = highest_order_bit_s(ts->selectmode);
+ if (selmode_max == SCE_SELECT_VERTEX) {
+ EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE);
+ }
+ }
+ em->selectmode = SCE_SELECT_EDGE;
+ }
+ ts->selectmode = em->selectmode;
+ EDBM_selectmode_set(em);
+ ret = TRUE;
+ break;
+ case SCE_SELECT_FACE:
+ if (use_extend == 0 || em->selectmode == 0) {
+ if (use_expand) {
+ const short selmode_max = highest_order_bit_s(ts->selectmode);
+ if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) {
+ EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE);
+ }
+ }
+
+ em->selectmode = SCE_SELECT_FACE;
+ }
+ ts->selectmode = em->selectmode;
+ EDBM_selectmode_set(em);
+ ret = TRUE;
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ if (ret == TRUE) {
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
+
+ return ret;
+}
void EDBM_deselect_by_material(BMEditMesh *em, const short index, const short select)
{
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 881e4bc02e2..58f05df83f1 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -129,6 +129,7 @@ void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot);
void MESH_OT_edges_select_sharp(struct wmOperatorType *ot);
void MESH_OT_select_shortest_path(struct wmOperatorType *ot);
void MESH_OT_select_similar(struct wmOperatorType *ot);
+void MESH_OT_select_mode(struct wmOperatorType *ot);
void MESH_OT_select_random(struct wmOperatorType *ot);
void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
void MESH_OT_mark_seam(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 4036e0c6822..95c4691e440 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -130,6 +130,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_edge_face_add);
WM_operatortype_append(MESH_OT_select_shortest_path);
WM_operatortype_append(MESH_OT_select_similar);
+ WM_operatortype_append(MESH_OT_select_mode);
WM_operatortype_append(MESH_OT_loop_multi_select);
WM_operatortype_append(MESH_OT_mark_seam);
WM_operatortype_append(MESH_OT_mark_sharp);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 3d2c4f95624..7d3d6861418 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -555,7 +555,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M
Key *key = me->key;
KeyBlock *kb;
- if (!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
+ if (!modifier_isSameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
return 0;
}
@@ -688,6 +688,13 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
return 0;
}
+ else if ((ob->mode & OB_MODE_SCULPT) &&
+ (find_multires_modifier_before(scene, md)) &&
+ (modifier_isSameTopology(md) == FALSE))
+ {
+ BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
+ return 0;
+ }
if (md != ob->modifiers.first)
BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
@@ -1000,7 +1007,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int apply_as = RNA_enum_get(op->ptr, "apply_as");
-
+
if (!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 58c6959d6f0..e7f09b4055a 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1225,7 +1225,7 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
return lay;
}
-static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->localvd) {
@@ -1233,7 +1233,7 @@ static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
else {
move_to_layer_init(C, op);
- return WM_operator_props_popup(C, op, event);
+ return WM_operator_props_dialog_popup(C, op, 260, 30);
}
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 05524af34f0..e56ca20dfcc 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -845,25 +845,26 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
{
MDeformVert *dv = NULL;
- BMVert *eve;
- Mesh *me;
/* get the deform vertices corresponding to the vertnum */
if (ob->type == OB_MESH) {
- me = ob->data;
+ Mesh *me = ob->data;
if (me->edit_btmesh) {
- eve = BM_vert_at_index(me->edit_btmesh->bm, vertnum);
+ /* warning, this lookup is _not_ fast */
+ BMVert *eve = BM_vert_at_index(me->edit_btmesh->bm, vertnum);
if (!eve) {
return 0.0f;
}
dv = CustomData_bmesh_get(&me->edit_btmesh->bm->vdata, eve->head.data, CD_MDEFORMVERT);
}
else {
- if (vertnum >= me->totvert) {
- return 0.0f;
+ if (me->dvert) {
+ if (vertnum >= me->totvert) {
+ return 0.0f;
+ }
+ dv = &me->dvert[vertnum];
}
- dv = &me->dvert[vertnum];
}
}
else if (ob->type == OB_LATTICE) {
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 0e82d8651f3..abfefba02b9 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -248,7 +248,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
{
- /* gatheravailable texture users in context. runs on every draw of
+ /* gather available texture users in context. runs on every draw of
* properties editor, before the buttons are created. */
ButsContextTexture *ct = sbuts->texuser;
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 02716c20588..d523d598925 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -1497,7 +1497,7 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
if (onlyv2d) {
/* if manual calibration is used then grease pencil data is already
- * drawed in draw_distortion */
+ * drawn in draw_distortion */
if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) {
glPushMatrix();
glMultMatrixf(sc->unistabmat);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 7270516aa51..00d4a943626 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1686,7 +1686,7 @@ static int sequencer_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
if (ar->regiontype == RGN_TYPE_WINDOW) {
/* bounding box of 30 pixels is used for markers shortcuts,
- * prevent conflict with markers shortcurts here
+ * prevent conflict with markers shortcuts here
*/
if (event->mval[1] <= 30)
return OPERATOR_PASS_THROUGH;
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 3413377c7b9..ec564e95c65 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -945,7 +945,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
ED_region_tag_redraw(ar);
break;
case NC_GPENCIL:
- if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
+ if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
ED_region_tag_redraw(ar);
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index d8fcc7e12e7..79bf003a563 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -310,21 +310,14 @@ static char *view3d_modeselect_pup(Scene *scene)
return (string);
}
-
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
{
wmWindow *win = CTX_wm_window(C);
- ToolSettings *ts = CTX_data_tool_settings(C);
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = NULL;
- int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
+ const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
PointerRNA props_ptr;
-
- if (obedit && obedit->type == OB_MESH) {
- em = BMEdit_FromObject(obedit);
- }
+
/* watch it: if sa->win does not exist, check that when calling direct drawing routines */
switch (event) {
@@ -336,42 +329,17 @@ static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
break;
case B_SEL_VERT:
- if (em) {
- if (shift == 0 || em->selectmode == 0)
- em->selectmode = SCE_SELECT_VERTEX;
- ts->selectmode = em->selectmode;
- EDBM_selectmode_set(em);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Vertex");
}
break;
case B_SEL_EDGE:
- if (em) {
- if (shift == 0 || em->selectmode == 0) {
- if ((em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX) {
- if (ctrl) EDBM_selectmode_convert(em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
- }
- em->selectmode = SCE_SELECT_EDGE;
- }
- ts->selectmode = em->selectmode;
- EDBM_selectmode_set(em);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Edge");
}
break;
case B_SEL_FACE:
- if (em) {
- if (shift == 0 || em->selectmode == 0) {
- if (((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) ||
- ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE))
- {
- if (ctrl) EDBM_selectmode_convert(em, (ts->selectmode ^ SCE_SELECT_FACE), SCE_SELECT_FACE);
- }
- em->selectmode = SCE_SELECT_FACE;
- }
- ts->selectmode = em->selectmode;
- EDBM_selectmode_set(em);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Face");
}
break;
@@ -430,9 +398,15 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
row = uiLayoutRow(layout, TRUE);
block = uiLayoutGetBlock(row);
- uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select - Shift-Click for multiple modes");
- uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select - Shift-Click for multiple modes");
- uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Face select - Shift-Click for multiple modes");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Vertex select - Shift-Click for multiple modes");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Edge select - Shift-Click for multiple modes, Ctrl-Click expands selection");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Face select - Shift-Click for multiple modes, Ctrl-Click expands selection");
}
}
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index e860d486ea3..3828064185e 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -1553,7 +1553,112 @@ static void UV_OT_align(wmOperatorType *ot)
/* properties */
RNA_def_enum(ot->srna, "axis", axis_items, 'a', "Axis", "Axis to align UV locations on");
}
+/* ******************** weld near operator **************** */
+typedef struct UVvert {
+ MLoopUV *uv_loop;
+ int weld;
+} UVvert;
+
+static int remove_doubles_exec(bContext *C, wmOperator *op)
+{
+ SpaceImage *sima;
+ Scene *scene;
+ Object *obedit;
+ Image *ima;
+ BMEditMesh *em;
+ MTexPoly *tf;
+ int UV_a;
+ int UV_b;
+ float UVp1[2];
+ float UVp2[2];
+ float weld_dist;
+ MLoopUV **loop_arr = NULL;
+ BLI_array_declare(loop_arr);
+
+ UVvert *vert_arr = NULL;
+ BLI_array_declare(vert_arr);
+ BMIter iter, liter;
+ BMFace *efa;
+ BMLoop *l;
+
+ sima = CTX_wm_space_image(C);
+ scene = CTX_data_scene(C);
+ obedit = CTX_data_edit_object(C);
+ em = BMEdit_FromObject(obedit);
+ ima = CTX_data_edit_image(C);
+
+ weld_dist = RNA_float_get(op->ptr, "weld_dist");
+
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ continue;
+
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (uvedit_uv_select_test(em, scene, l)) {
+ MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ UVvert vert;
+ vert.uv_loop = luv;
+ vert.weld = FALSE;
+ BLI_array_append(vert_arr, vert);
+ }
+
+ }
+ }
+
+ for (UV_a = 0; UV_a<BLI_array_count(vert_arr); UV_a++){
+ if (vert_arr[UV_a].weld == FALSE){
+ float far_UV [2];
+ float near_UV [2];
+
+ BLI_array_empty(loop_arr);
+ BLI_array_append(loop_arr, vert_arr[UV_a].uv_loop);
+
+ copy_v2_v2(UVp1, vert_arr[UV_a].uv_loop->uv);
+
+ copy_v2_v2(near_UV, UVp1);
+ copy_v2_v2(far_UV, UVp1);
+
+ vert_arr[UV_a].weld = TRUE;
+ for (UV_b = 0; UV_b<BLI_array_count(vert_arr); UV_b++){
+ copy_v2_v2(UVp2, vert_arr[UV_b].uv_loop->uv);
+ if (UV_b != UV_a && vert_arr[UV_b].weld == FALSE && UVp1[0]-UVp2[0] > -weld_dist && UVp1[0] - UVp2[0] < weld_dist && UVp1[1] - UVp2[1] > -weld_dist && UVp1[1] - UVp2[1] < weld_dist){
+ minmax_v2v2_v2(near_UV, far_UV, UVp2);
+ BLI_array_append(loop_arr, vert_arr[UV_b].uv_loop);
+ vert_arr[UV_b].weld = TRUE;
+ }
+ }
+ for (UV_b = 0; UV_b<BLI_array_count(loop_arr); UV_b++){
+ mid_v2_v2v2(loop_arr[UV_b]->uv, far_UV, near_UV);
+ }
+ }
+ }
+ BLI_array_free(loop_arr);
+ BLI_array_free(vert_arr);
+
+ uvedit_live_unwrap_update(sima, scene, obedit);
+ DAG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UV_OT_remove_doubles(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Doubles";
+ ot->description = "Selected UV vertices that are within a radius of eachother are welded together";
+ ot->idname = "UV_OT_remove_doubles";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = remove_doubles_exec;
+ ot->poll = ED_operator_uvedit;
+
+ RNA_def_float(ot->srna, "weld_dist", 0.02f, 0.0f, 1.0f, "Weld Distance", "Maximum distance between welded vertices", 0.001f, 10.0f);
+}
/* ******************** weld operator **************** */
static int weld_exec(bContext *C, wmOperator *UNUSED(op))
@@ -3776,6 +3881,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_seams_from_islands);
WM_operatortype_append(UV_OT_mark_seam);
WM_operatortype_append(UV_OT_weld);
+ WM_operatortype_append(UV_OT_remove_doubles);
WM_operatortype_append(UV_OT_pin);
WM_operatortype_append(UV_OT_average_islands_scale);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index b1945c37048..e10d70d48d1 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -1444,18 +1444,22 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
}
case PADENTER:
case RETKEY:
- if (stitch_process_data(stitch_state, scene, 1)) {
- stitch_exit(C, op, 1);
- return OPERATOR_FINISHED;
+ if (event->val == KM_PRESS) {
+ if (stitch_process_data(stitch_state, scene, 1)) {
+ stitch_exit(C, op, 1);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return stitch_cancel(C, op);
+ }
}
else {
- return stitch_cancel(C, op);
+ return OPERATOR_PASS_THROUGH;
}
-
/* Increase limit */
case PADPLUSKEY:
case WHEELUPMOUSE:
- if (event->alt) {
+ if (event->val == KM_PRESS && event->alt) {
stitch_state->limit_dist += 0.01f;
if (!stitch_process_data(stitch_state, scene, 0)) {
return stitch_cancel(C, op);
@@ -1468,7 +1472,7 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
/* Decrease limit */
case PADMINUS:
case WHEELDOWNMOUSE:
- if (event->alt) {
+ if (event->val == KM_PRESS && event->alt) {
stitch_state->limit_dist -= 0.01f;
stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist);
if (!stitch_process_data(stitch_state, scene, 0)) {
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index f615902eedf..fc60c5a3a0f 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -1414,7 +1414,7 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
BMIter liter;
MLoopUV *luv;
float **uvs = NULL;
- BLI_array_fixedstack_declare(uvs, BM_NGON_STACK_SIZE, efa->len, __func__);
+ BLI_array_fixedstack_declare(uvs, BM_DEFAULT_NGON_STACK_SIZE, efa->len, __func__);
float dx;
int i, mi;
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
index 08d2789451c..efe07b2c48c 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.c
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -79,12 +79,14 @@ static IKPlugin ikplugin_tab[] = {
itasc_update_param,
itasc_test_constraint,
},
- #endif
+#endif
+
+ { NULL }
};
static IKPlugin *get_plugin(bPose *pose)
{
- if (!pose || pose->iksolver < 0 || pose->iksolver >= (sizeof(ikplugin_tab) / sizeof(IKPlugin)))
+ if (!pose || pose->iksolver < 0 || pose->iksolver > (sizeof(ikplugin_tab)/sizeof(IKPlugin) - 2))
return NULL;
return &ikplugin_tab[pose->iksolver];
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index b9774a9f7b0..3fd31f9a58c 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -164,7 +164,7 @@ typedef struct ColormanageProcessor {
* but they holds indexes of all transformations and color spaces, not
* their names.
*
- * This helps avoid extra colorsmace / display / view lookup without
+ * This helps avoid extra colorspace / display / view lookup without
* requiring to pass all variables which affects on display buffer
* to color management cache system and keeps calls small and nice.
*/
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index d94f6368298..3a2bf99c75c 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -387,8 +387,8 @@ BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
/*
* 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space
*
- * - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the imager is used
- * - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the imager is used
+ * - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the image is used
+ * - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the image is used
*/
/* ****************************** COPIED FROM image_to_j2k.c */
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index d96a01d7093..758617bdd48 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -348,25 +348,12 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
g = *buffer++;
b = *buffer++;
k = *buffer++;
-
- k = 255 - k;
- r -= k;
- if (r & 0xffffff00) {
- if (r < 0) r = 0;
- else r = 255;
- }
- g -= k;
- if (g & 0xffffff00) {
- if (g < 0) g = 0;
- else g = 255;
- }
- b -= k;
- if (b & 0xffffff00) {
- if (b < 0) b = 0;
- else b = 255;
- }
-
- rect[3] = 255 - k;
+
+ r = (r * k) / 255;
+ g = (g * k) / 255;
+ b = (b * k) / 255;
+
+ rect[3] = 255;
rect[2] = b;
rect[1] = g;
rect[0] = r;
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 60c6e184070..5d2632ec0d7 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -881,7 +881,7 @@ void IMB_exr_close(void *handle)
/* get a substring from the end of the name, separated by '.' */
static int imb_exr_split_token(const char *str, const char *end, const char **token)
{
- int maxlen = end - str;
+ ptrdiff_t maxlen = end - str;
int len = 0;
while (len < maxlen && *(end - len - 1) != '.') {
len++;
@@ -1183,7 +1183,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
frameBuffer.insert(exr_rgba_channelname(file, "B"),
Slice(Imf::FLOAT, (char *) (first + 2), xstride, ystride));
- /* 1.0 is fill value, this still neesd to be assigned even when (is_alpha == 0) */
+ /* 1.0 is fill value, this still needs to be assigned even when (is_alpha == 0) */
frameBuffer.insert(exr_rgba_channelname(file, "A"),
Slice(Imf::FLOAT, (char *) (first + 3), xstride, ystride, 1, 1, 1.0f));
diff --git a/source/blender/imbuf/intern/openexr/openexr_multi.h b/source/blender/imbuf/intern/openexr/openexr_multi.h
index 78071975c72..376d2401b1c 100644
--- a/source/blender/imbuf/intern/openexr/openexr_multi.h
+++ b/source/blender/imbuf/intern/openexr/openexr_multi.h
@@ -35,10 +35,10 @@
/* experiment with more advanced exr api */
-/* Note: as for now openexr only supports 32 chars in channel names.
- * This api also supports max 8 channels per pass now. easy to fix! */
-#define EXR_LAY_MAXNAME 51
-#define EXR_PASS_MAXNAME 11
+/* XXX layer+pass name max 64? */
+/* This api also supports max 8 channels per pass now. easy to fix! */
+#define EXR_LAY_MAXNAME 64
+#define EXR_PASS_MAXNAME 64
#define EXR_TOT_MAXNAME 64
#define EXR_PASS_MAXCHAN 8
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index b7c1ee675b3..b64fc08a47a 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -50,12 +50,13 @@ typedef struct bGPDspoint {
*/
typedef struct bGPDstroke {
struct bGPDstroke *next, *prev;
-
bGPDspoint *points; /* array of data-points for stroke */
+ void *pad; /* keep 4 pointers at the beginning, padding for 'inittime' is tricky 64/32bit */
int totpoints; /* number of data-points in array */
short thickness; /* thickness of stroke (currently not used) */
short flag; /* various settings about this stroke */
+
double inittime; /* Init time of stroke */
} bGPDstroke;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 248faf5a242..3e226135741 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1201,7 +1201,7 @@ typedef struct Scene {
#define R_NO_OVERWRITE 0x400000 /* skip existing files */
#define R_TOUCH 0x800000 /* touch files before rendering */
#define R_SIMPLIFY 0x1000000
-#define R_EDGE_FRS 0x2000000 /* R_EDGE for Freestyle */
+#define R_EDGE_FRS 0x2000000 /* R_EDGE reserved for Freestyle */
#define R_PERSISTENT_DATA 0x4000000 /* keep data around for re-render */
/* seq_flag */
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
index 9c80d30bca4..12819303b26 100644
--- a/source/blender/makesdna/DNA_tracking_types.h
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -163,7 +163,7 @@ typedef struct MovieTrackingSettings {
/* ** reconstruction settings ** */
int keyframe1 DNA_DEPRECATED,
- keyframe2 DNA_DEPRECATED; /* two keyframes for reconstrution initialization
+ keyframe2 DNA_DEPRECATED; /* two keyframes for reconstruction initialization
* were moved to per-tracking object settings
*/
@@ -228,7 +228,7 @@ typedef struct MovieTrackingObject {
MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */
/* reconstruction options */
- int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */
+ int keyframe1, keyframe2; /* two keyframes for reconstruction initialization */
} MovieTrackingObject;
typedef struct MovieTrackingStats {
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 1e1a8c82b8e..21aed20ccc3 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -1424,7 +1424,7 @@ static void rna_def_curve(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_map_taper", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_MAP_TAPER);
- RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually bevelled curve");
+ RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually beveled curve");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
/* texture space */
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index e5f44644f7a..f83410e7cc1 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -555,7 +555,7 @@ static void rna_Window_screen_set(PointerRNA *ptr, PointerRNA value)
if (value.data == NULL)
return;
- /* exception: can't set screens inside of area/region handers */
+ /* exception: can't set screens inside of area/region handlers */
win->newscreen = value.data;
}
@@ -563,8 +563,8 @@ static void rna_Window_screen_update(bContext *C, PointerRNA *ptr)
{
wmWindow *win = (wmWindow *)ptr->data;
- /* exception: can't set screens inside of area/region handers, and must
- * use context so notifier gets to the right window */
+ /* exception: can't set screens inside of area/region handlers,
+ * and must use context so notifier gets to the right window */
if (win->newscreen) {
WM_event_add_notifier(C, NC_SCREEN | ND_SCREENBROWSE, win->newscreen);
win->newscreen = NULL;
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 19be2b6a62e..e98af997507 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -2784,7 +2784,7 @@ static struct PyMethodDef Vector_methods[] = {
/* Note
* Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing
* but this means for eg that
- * (vec * mat) and (mat * vec) both get sent to Vector_mul and it neesd to sort out the order
+ * (vec * mat) and (mat * vec) both get sent to Vector_mul and it needs to sort out the order
*/
PyDoc_STRVAR(vector_doc,
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 1331c287d7c..d2ffc3a0e26 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -60,6 +60,7 @@ struct Scene;
#define RE_ENGINE_PREVIEW 2
#define RE_ENGINE_DO_DRAW 4
#define RE_ENGINE_DO_UPDATE 8
+#define RE_ENGINE_RENDERING 16
extern ListBase R_engines;
diff --git a/source/blender/render/intern/raytrace/rayobject_internal.h b/source/blender/render/intern/raytrace/rayobject_internal.h
index 92ac39909a8..aa8ab8c3da4 100644
--- a/source/blender/render/intern/raytrace/rayobject_internal.h
+++ b/source/blender/render/intern/raytrace/rayobject_internal.h
@@ -92,7 +92,7 @@ int RE_rayobjectcontrol_test_break(RayObjectControl *c);
* eg.: on render code)
*
* 0 means it's reserved and has it own meaning inside each ray acceleration structure
- * (this way each structure can use the allign offset to determine if a node represents a
+ * (this way each structure can use the align offset to determine if a node represents a
* RayObject primitive, which can be used to save memory)
*/
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
index 77e9dc9d8fd..afb8fe6c3b5 100644
--- a/source/blender/render/intern/raytrace/rayobject_octree.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -1026,7 +1026,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
labdao = ddalabda;
- /* traversing ocree nodes need careful detection of smallest values, with proper
+ /* traversing octree nodes need careful detection of smallest values, with proper
* exceptions for equal labdas */
eqval = (labdax == labday);
if (labday == labdaz) eqval += 2;
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
index bae65c492f4..4195b103811 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
@@ -435,7 +435,7 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
/*
* Helper code
* PARTITION code / used on mean-split
- * basicly this a std::nth_element (like on C++ STL algorithm)
+ * basically this a std::nth_element (like on C++ STL algorithm)
*/
#if 0
static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis)
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 8bdb805ada2..9053bc84bbc 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -316,6 +316,7 @@ int RE_engine_render(Render *re, int do_all)
{
RenderEngineType *type = RE_engines_find(re->r.engine);
RenderEngine *engine;
+ int persistent_data = re->r.mode & R_PERSISTENT_DATA;
/* verify if we can render */
if (!type->render)
@@ -349,11 +350,17 @@ int RE_engine_render(Render *re, int do_all)
re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0;
/* render */
- if (!re->engine)
- re->engine = RE_engine_create(type);
-
engine = re->engine;
+ if (!engine) {
+ engine = RE_engine_create(type);
+
+ if (persistent_data)
+ re->engine = engine;
+ }
+
+ engine->flag |= RE_ENGINE_RENDERING;
+
/* TODO: actually link to a parent which shouldn't happen */
engine->re = re;
@@ -382,8 +389,13 @@ int RE_engine_render(Render *re, int do_all)
if (type->render)
type->render(engine, re->scene);
- if (!(re->r.mode & R_PERSISTENT_DATA)) {
- RE_engine_free(re->engine);
+ engine->tile_x = 0;
+ engine->tile_y = 0;
+ engine->flag &= ~RE_ENGINE_RENDERING;
+
+ /* re->engine becomes zero if user changed active render engine during render */
+ if (!persistent_data || !re->engine) {
+ RE_engine_free(engine);
re->engine = NULL;
}
@@ -393,8 +405,6 @@ int RE_engine_render(Render *re, int do_all)
BLI_rw_mutex_unlock(&re->resultmutex);
}
- engine->tile_x = 0;
- engine->tile_y = 0;
freeparts(re);
render_result_free_list(&engine->fullresult, engine->fullresult.first);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index aab7f442249..23065e5bd84 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -435,7 +435,10 @@ void RE_FreePersistentData(void)
/* render engines can be kept around for quick re-render, this clears all */
for (re = RenderGlobal.renderlist.first; re; re = re->next) {
if (re->engine) {
- RE_engine_free(re->engine);
+ /* if engine is currently rendering, just tag it to be freed when render is finished */
+ if (!(re->engine->flag & RE_ENGINE_RENDERING))
+ RE_engine_free(re->engine);
+
re->engine = NULL;
}
}
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
index e4a42fcd675..e812b99287c 100644
--- a/source/blender/render/intern/source/sunsky.c
+++ b/source/blender/render/intern/source/sunsky.c
@@ -118,8 +118,8 @@ static void DirectionToThetaPhi(float *toSun, float *theta, float *phi)
/**
* PerezFunction:
- * compute perez function value based on input paramters
- * */
+ * compute perez function value based on input parameters
+ */
static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, float gamma, float lvz)
{
float den, num;
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 7aa2b403897..024b6017699 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -545,7 +545,7 @@ static wmKeyMap *wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKe
/* copy new keymap from an existing one */
if (usermap && !(usermap->flag & KEYMAP_DIFF)) {
- /* for compatibiltiy with old user preferences with non-diff
+ /* for compatibility with old user preferences with non-diff
* keymaps we override the original entirely */
wmKeyMapItem *kmi, *orig_kmi;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 054e48f0bfb..126d497e08e 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -624,7 +624,7 @@ void WM_operator_properties_sanitize(PointerRNA *ptr, const short no_context)
/** set all props to their default,
* \param do_update Only update un-initialized props.
*
- * \note, theres nothing spesific to operators here.
+ * \note, theres nothing specific to operators here.
* this could be made a general function.
*/
int WM_operator_properties_default(PointerRNA *ptr, const int do_update)
@@ -1186,6 +1186,8 @@ static void wm_operator_ui_popup_ok(struct bContext *C, void *arg, int retval)
if (op && retval > 0)
WM_operator_call(C, op);
+
+ MEM_freeN(data);
}
int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
@@ -1280,6 +1282,31 @@ static void WM_OT_debug_menu(wmOperatorType *ot)
RNA_def_int(ot->srna, "debug_value", 0, SHRT_MIN, SHRT_MAX, "Debug Value", "", -10000, 10000);
}
+/* ***************** Operator defaults ************************* */
+static int wm_operator_defaults_exec(bContext *C, wmOperator *op)
+{
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "active_operator", &RNA_Operator);
+
+ if (!ptr.data) {
+ BKE_report(op->reports, RPT_ERROR, "No operator in context");
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_operator_properties_reset((wmOperator *)ptr.data);
+ return OPERATOR_FINISHED;
+}
+
+/* used by operator preset menu. pre-2.65 this was a 'Reset' button */
+static void WM_OT_operator_defaults(wmOperatorType *ot)
+{
+ ot->name = "Restore Defaults";
+ ot->idname = "WM_OT_operator_defaults";
+ ot->description = "Set the active operator to its default values";
+
+ ot->exec = wm_operator_defaults_exec;
+
+ ot->flag = OPTYPE_INTERNAL;
+}
/* ***************** Splash Screen ************************* */
@@ -3748,6 +3775,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_memory_statistics);
WM_operatortype_append(WM_OT_dependency_relations);
WM_operatortype_append(WM_OT_debug_menu);
+ WM_operatortype_append(WM_OT_operator_defaults);
WM_operatortype_append(WM_OT_splash);
WM_operatortype_append(WM_OT_search_menu);
WM_operatortype_append(WM_OT_call_menu);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index a965cbf82d6..fbb3466032d 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -351,7 +351,7 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
(GHOST_TWindowState)win->windowstate,
GHOST_kDrawingContextTypeOpenGL,
0 /* no stereo */,
- multisamples /* AA */);
+ multisamples /* AA */);
if (ghostwin) {
/* needed so we can detect the graphics card below */
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 4f3d020a3d9..cfccb8e8ced 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -1693,8 +1693,8 @@ PyMethodDef KX_GameObject::Methods[] = {
PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name),
KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
- KX_PYATTRIBUTE_RO_FUNCTION("group_children", KX_GameObject, pyattr_get_group_children),
- KX_PYATTRIBUTE_RO_FUNCTION("group_parent", KX_GameObject, pyattr_get_group_parent),
+ KX_PYATTRIBUTE_RO_FUNCTION("groupMembers", KX_GameObject, pyattr_get_group_members),
+ KX_PYATTRIBUTE_RO_FUNCTION("groupObject", KX_GameObject, pyattr_get_group_object),
KX_PYATTRIBUTE_RO_FUNCTION("scene", KX_GameObject, pyattr_get_scene),
KX_PYATTRIBUTE_RO_FUNCTION("life", KX_GameObject, pyattr_get_life),
KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass),
@@ -1991,7 +1991,7 @@ PyObject *KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE
Py_RETURN_NONE;
}
-PyObject *KX_GameObject::pyattr_get_group_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+PyObject *KX_GameObject::pyattr_get_group_members(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
CListValue* instances = self->GetInstanceObjects();
@@ -2012,7 +2012,7 @@ PyObject* KX_GameObject::pyattr_get_scene(void *self_v, const KX_PYATTRIBUTE_DEF
Py_RETURN_NONE;
}
-PyObject *KX_GameObject::pyattr_get_group_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+PyObject *KX_GameObject::pyattr_get_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
KX_GameObject* pivot = self->GetDupliGroupObject();
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index d5ae13eb702..e71af674a79 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -989,8 +989,8 @@ public:
static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
- static PyObject* pyattr_get_group_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
- static PyObject* pyattr_get_group_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_group_members(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_scene(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index 9430179e344..0188a7e15b8 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -76,7 +76,7 @@ PyMethodDef KX_MeshProxy::Methods[] = {
{"getVertex", (PyCFunction)KX_MeshProxy::sPyGetVertex,METH_VARARGS},
{"getPolygon", (PyCFunction)KX_MeshProxy::sPyGetPolygon,METH_VARARGS},
{"transform", (PyCFunction)KX_MeshProxy::sPyTransform,METH_VARARGS},
- {"transform_uv", (PyCFunction)KX_MeshProxy::sPyTransformUV,METH_VARARGS},
+ {"transformUV", (PyCFunction)KX_MeshProxy::sPyTransformUV,METH_VARARGS},
//{"getIndexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetIndexArrayLength,METH_VARARGS},
{NULL,NULL} //Sentinel
};