diff options
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 13 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_geom.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 12 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 11 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels_edit.c | 57 |
5 files changed, 66 insertions, 28 deletions
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index e33f4a7feab..531291c30bb 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -2792,9 +2792,22 @@ void BKE_mesh_recalc_looptri( } else if (mp_totloop == 4) { ML_TO_MLT(0, 1, 2); + MLoopTri *mlt_a = mlt; mlooptri_index++; ML_TO_MLT(0, 2, 3); + MLoopTri *mlt_b = mlt; mlooptri_index++; + + if (UNLIKELY(is_quad_flip_v3_first_third_fast( + mvert[mloop[mlt_a->tri[0]].v].co, + mvert[mloop[mlt_a->tri[1]].v].co, + mvert[mloop[mlt_a->tri[2]].v].co, + mvert[mloop[mlt_b->tri[2]].v].co))) + { + /* flip out of degenerate 0-2 state. */ + mlt_a->tri[2] = mlt_b->tri[2]; + mlt_b->tri[0] = mlt_a->tri[1]; + } } #endif /* USE_TESSFACE_SPEEDUP */ else { diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 933e31ba84b..ffe0ce11cef 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -85,6 +85,7 @@ bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); bool is_poly_convex_v2(const float verts[][2], unsigned int nr); int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +bool is_quad_flip_v3_first_third_fast(const float v0[3], const float v1[3], const float v2[3], const float v3[3]); /********************************* Distance **********************************/ diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index d3080e5530f..a3d850f9551 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -4903,6 +4903,18 @@ int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], con return ret; } +bool is_quad_flip_v3_first_third_fast(const float v1[3], const float v2[3], const float v3[3], const float v4[3]) +{ + float d_12[3], d_13[3], d_14[3]; + float cross_a[3], cross_b[3]; + sub_v3_v3v3(d_12, v2, v1); + sub_v3_v3v3(d_13, v3, v1); + sub_v3_v3v3(d_14, v4, v1); + cross_v3_v3v3(cross_a, d_12, d_13); + cross_v3_v3v3(cross_b, d_14, d_13); + return dot_v3v3(cross_a, cross_b) > 0.0f; +} + /** * Return the value which the distance between points will need to be scaled by, * to define a handle, given both points are on a perfect circle. diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 66fcd739839..66d0a83eb9f 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -1426,6 +1426,17 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri (l_ptr_a[2] = l_ptr_b[1] = l = l->next); ( l_ptr_b[2] = l->next); #endif + + if (UNLIKELY(is_quad_flip_v3_first_third_fast( + l_ptr_a[0]->v->co, + l_ptr_a[1]->v->co, + l_ptr_a[2]->v->co, + l_ptr_b[2]->v->co))) + { + /* flip out of degenerate 0-2 state. */ + l_ptr_a[2] = l_ptr_b[2]; + l_ptr_b[0] = l_ptr_a[1]; + } } #endif /* USE_TESSFACE_SPEEDUP */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 0db465e583b..5d5990b9a0a 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -225,6 +225,33 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat ANIM_animdata_freelist(&anim_data); } +static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp, bAnimListElem *ale) +{ + /* Armatures-Specific Feature: + * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737) + */ + if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) { + if ((ale->id) && (GS(ale->id->name) == ID_OB)) { + Object *ob = (Object *)ale->id; + if (ob->type == OB_ARMATURE) { + /* Assume for now that any group with corresponding name is what we want + * (i.e. for an armature whose location is animated, things would break + * if the user were to add a bone named "Location"). + * + * TODO: check the first F-Curve or so to be sure... + */ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name); + if (agrp->flag & AGRP_SELECTED) { + ED_pose_bone_select(ob, pchan, true); + } + else { + ED_pose_bone_select(ob, pchan, false); + } + } + } + } +} + /* Deselect all animation channels * - data: pointer to datatype, as contained in bAnimContext * - datatype: the type of data that 'data' represents (eAnimCont_Types) @@ -345,8 +372,8 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d case ANIMTYPE_GROUP: { bActionGroup *agrp = (bActionGroup *)ale->data; - ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED); + select_pchan_for_action_group(ac, agrp, ale); agrp->flag &= ~AGRP_ACTIVE; break; } @@ -2398,33 +2425,7 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec case ANIMTYPE_GROUP: { bActionGroup *agrp = (bActionGroup *)ale->data; - - /* Armatures-Specific Feature: - * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737) - */ - if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) { - if ((ale->id) && (GS(ale->id->name) == ID_OB)) { - Object *ob = (Object *)ale->id; - - if (ob->type == OB_ARMATURE) { - /* Assume for now that any group with corresponding name is what we want - * (i.e. for an armature whose location is animated, things would break - * if the user were to add a bone named "Location"). - * - * TODO: check the first F-Curve or so to be sure... - */ - bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name); - - if (agrp->flag & AGRP_SELECTED) { - ED_pose_bone_select(ob, pchan, true); - } - else { - ED_pose_bone_select(ob, pchan, false); - } - } - } - } - + select_pchan_for_action_group(ac, agrp, ale); /* always clear active flag after doing this */ agrp->flag &= ~AGRP_ACTIVE; break; |