// Figure out if we can collapse edge eid=[a,b] under current constraint set.
        // First we resolve vertex constraints using can_collapse_vtx(). However this
        // does not catch some topological cases at the edge-constraint level, which
        // which we will only be able to detect once we know if we are losing a or b.
        // See comments on can_collapse_vtx() for what collapse_to is for.
        protected bool can_collapse_constraints(int eid, int a, int b, int c, int d, int tc, int td, out int collapse_to)
        {
            collapse_to = -1;
            if (constraints == null)
            {
                return(true);
            }

            bool bVtx = can_collapse_vtx(eid, a, b, out collapse_to);

            if (bVtx == false)
            {
                return(false);
            }

            // when we lose a vtx in a collapse, we also lose two edges [iCollapse,c] and [iCollapse,d].
            // If either of those edges is constrained, we would lose that constraint.
            // This would be bad.
            int iCollapse = (collapse_to == a) ? b : a;

            if (c != DMesh3.InvalidID)
            {
                int ec = mesh.FindEdgeFromTri(iCollapse, c, tc);
                if (constraints.GetEdgeConstraint(ec).IsUnconstrained == false)
                {
                    return(false);
                }
            }
            if (d != DMesh3.InvalidID)
            {
                int ed = mesh.FindEdgeFromTri(iCollapse, d, td);
                if (constraints.GetEdgeConstraint(ed).IsUnconstrained == false)
                {
                    return(false);
                }
            }

            return(true);
        }