Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Thu, 8 Feb 2018 12:48:36 +0000 (23:48 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 8 Feb 2018 12:48:36 +0000 (23:48 +1100)
source/blender/blenkernel/intern/mesh_evaluate.c
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/intern/math_geom.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/editors/animation/anim_channels_edit.c

index e33f4a7feab4fe1bb72ee59fdb0a3e41bff99a9a..531291c30bb60dfdbc16575b4057b3b09648f5f6 100644 (file)
@@ -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 {
index 933e31ba84bfc2a93be9dceeb9e90f6231a078a4..ffe0ce11ceff264751663bca48cd9cbc25d8c8cd 100644 (file)
@@ -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 **********************************/
 
index d3080e5530f84e854c36416ea7a4c4c505c3655b..a3d850f9551736ddc7aa050fe74236547927f39e 100644 (file)
@@ -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.
index 66fcd7398390de8957dfc2894fc14ab35fe30b07..66d0a83eb9fd2b8289bb75be300e4fe038a49b81 100644 (file)
@@ -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 */
index 0db465e583bdff8fa28b4469a1f158db69304b68..5d5990b9a0a2b39dc1461855bb5240c0e8be4970 100644 (file)
@@ -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;