public override void Apply(Frame3f vNextPos, int tid)
        {
            if (MapSourceF == null)
            {
                f3.DebugUtil.Log("[VectorDisplacementBaseBrush] .MapSourceF is null!");
                return;
            }
            VectorDisplacement use_map = MapSourceF();

            if (use_map == null || use_map.Count != Mesh.MaxVertexID)
            {
                return;
            }

            DijkstraGraphDistance dj = Dijkstra;

            dj.Reset();

            Index3i  ti = Mesh.GetTriangle(tid);
            Vector3d c  = Mesh.GetTriCentroid(tid);

            dj.AddSeed(ti.a, (float)Mesh.GetVertex(ti.a).Distance(c));
            dj.AddSeed(ti.b, (float)Mesh.GetVertex(ti.b).Distance(c));
            dj.AddSeed(ti.c, (float)Mesh.GetVertex(ti.c).Distance(c));
            double compute_Dist = MathUtil.SqrtTwo * Radius;

            dj.ComputeToMaxDistance((float)compute_Dist);

            ApplyCurrentStamp(vNextPos, tid, dj, use_map);

            mesh_changed();
        }
        protected override void ApplyCurrentStamp(Frame3f vCenter, int tid, DijkstraGraphDistance dj, VectorDisplacement map)
        {
            Vector3d c = Vector3d.Zero, v = Vector3d.Zero, o = vCenter.Origin;
            double   r = Radius;

            List <int> order = dj.GetOrder();
            int        N     = order.Count;

            for (int k = 0; k < N; ++k)
            {
                int vid = order[k];
                v = Mesh.GetVertex(vid);
                double d = v.Distance(ref o);
                double t = MathUtil.Clamp(d / r, 0.0, 1.0);
                t = 1 - t * t;
                t = t * t * t;
                //t = MathUtil.WyvillFalloff01(t);


                v = map[vid];
                c = Vector3d.Zero; int n = 0;
                foreach (int nbrid in Mesh.VtxVerticesItr(vid))
                {
                    c += map[nbrid];
                    n++;
                }
                c /= n;

                map[vid] = Vector3d.Lerp(ref v, ref c, SmoothPower * t);
            }
        }
        protected override void ApplyCurrentStamp(Frame3f vCenter, int tid, DijkstraGraphDistance dj, VectorDisplacement map)
        {
            List <int> order = dj.GetOrder();
            int        N     = order.Count;

            for (int k = 0; k < N; ++k)
            {
                int    vid = order[k];
                double d   = (Mesh.GetVertex(vid) - vCenter.Origin).Length;
                double t   = MathUtil.Clamp(d / Radius, 0.0, 1.0);
                t        = Power * MathUtil.WyvillFalloff01(t);
                map[vid] = Vector3d.Lerp(map[vid], Vector3d.Zero, t);
            }
        }
        protected override void ApplyCurrentStamp(Frame3f vCenter, int tid, DijkstraGraphDistance dj, VectorDisplacement map)
        {
            Vector3d n = Mesh.GetTriNormal(tid);

            List <int> order = dj.GetOrder();
            int        N     = order.Count;

            for (int k = 0; k < N; ++k)
            {
                int vid = order[k];
                //double d = dj.GetDistance(vid);
                double d = (Mesh.GetVertex(vid) - vCenter.Origin).Length;
                double t = MathUtil.Clamp(d / Radius, 0.0, 1.0);
                t = MathUtil.WyvillFalloff01(t);
                Vector3d offset = Power * t * n;
                if (Invert)
                {
                    map[vid] = map[vid] - offset;
                }
                else
                {
                    map[vid] = map[vid] + offset;
                }
            }
        }
 /// <summary>
 /// Subclass implements this
 /// </summary>
 protected abstract void ApplyCurrentStamp(Frame3f vCenter, int tid, DijkstraGraphDistance dj, VectorDisplacement map);