private void SetData(ParamMorph value)
        {
            if(value == data)
                return;

            data    = value;

            UpdateUI();
        }
        public void ImportOld(string filename, ModelFile model)
        {
            var importer    = new DaeIMImpoter();
            Root            = importer.Import(filename);

            var skins       = Root.Instances.OfType<SkinDeclaraion>    ().ToArray();
            var morphs      = Root.Instances.OfType<MorphingDeclaraion>().ToArray();
            var geoms       = Root.Instances.OfType<Geometry>          ().ToArray();
            Vertices        = new Dictionary<ModelVertex, int>();
            Indices         = new List<int>();
              //Skins           = new Dictionary<int, ModelSkin>();

            if(morphs.Length > 0)
            {
                var geom    = morphs.First().Source as Geometry;
                var mesh    = geom.Get<Mesh>("Data");
                var posch   = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Position);
                var nrmch   = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Normal);
                var texch   = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.TexCoord);
                var pos     = posch.GetDataAsList<SlimDX.Vector3>();
                var nrm     = nrmch.GetDataAsList<SlimDX.Vector3>();
                var tex     = texch.GetDataAsList<SlimDX.Vector2>();
                var posface = posch.GetIndicesAsList(mesh);
                var nrmface = nrmch.GetIndicesAsList(mesh);
                var texface = texch.GetIndicesAsList(mesh);
                var numidx  = posface.Count;

                for(int i= 0; i < numidx; ++i)
                {
                    var p   = pos[posface[i]];
                    var n   = nrm[nrmface[i]];
                    var t   = tex[texface[i]];
                    var v   = new ModelVertex()
                    {
                        P   = new Vector3(p.X, p.Y, p.Z),
                        N   = new Vector3(n.X, n.Y, n.Z),
                        T   = new Vector2(t.X, t.Y),
                    };

                    int index;

                    if(!Vertices.TryGetValue(v, out index))
                        Vertices.Add(v, index= Vertices.Count);

                    Indices.Add(index);
                }

                var prims   = new List<ModelPrimitive>();
                var start   = 0;

                foreach(var i in mesh.Primitives)
                {
                    var prim        = new ModelPrimitive();
                    prim.Indices    = Indices.Skip(start).Take(i.Count).Select(j => (ushort)j).ToList();
                    prim.NumIndices = Indices.Count;
                    start           +=Indices.Count;

                    prims.Add(prim);
                }

                model.Mesh.Skins        = Vertices.Keys
                    .Select(i => model.Mesh.Skins[FindClosest(model.Mesh.Vertices, i.P)])
                    .ToList();
                model.Mesh.Vertices     = Vertices.Keys.ToList();
                model.Mesh.NumVerts     = model.Mesh.Vertices.Count;
                model.Mesh.Primitives   = prims;
                model.Mesh.NumPrims     = prims.Count;

                // モーフィング
                model.Params    = model.Params.Where(i => !(i is ParamMorph)).ToList();

                foreach(var i in morphs.First().Channels)
                {
                    var mmesh   = i.Geometry.Get<Mesh>("Data");
                    var mposch  = mmesh.Channels.FirstOrDefault(j => j.Semantic == GeometrySemantic.Position);
                    var mpos    = mposch.GetDataAsList<SlimDX.Vector3>();
                    var mposidx = mposch.GetIndicesAsList(mmesh);
                    var dic     = new Dictionary<int, MorphVertex>();
                    var mnrm    = new SlimDX.Vector3[mpos.Count];

                    // 法線計算
                    for(int j= 0; j < mposidx.Count; j+=3)
                    {
                        var a   = mpos[mposidx[j+0]];
                        var b   = mpos[mposidx[j+1]];
                        var c   = mpos[mposidx[j+2]];
                        var ab  = SlimDX.Vector3.Normalize(SlimDX.Vector3.Subtract(b, a));
                        var ac  = SlimDX.Vector3.Normalize(SlimDX.Vector3.Subtract(c, a));
                        var n   = SlimDX.Vector3.Normalize(SlimDX.Vector3.Cross(ab, ac));

                        mnrm[mposidx[j+0]]  = SlimDX.Vector3.Add(mnrm[mposidx[j+0]], n);
                        mnrm[mposidx[j+1]]  = SlimDX.Vector3.Add(mnrm[mposidx[j+1]], n);
                        mnrm[mposidx[j+2]]  = SlimDX.Vector3.Add(mnrm[mposidx[j+2]], n);
                    }

                    for(int j= 0; j < mnrm.Length; ++j)
                        mnrm[j] = SlimDX.Vector3.Normalize(mnrm[j]);

                    for(int j= 0; j < mposidx.Count; ++j)
                    {
                        var ii  = (ushort)Indices[j];
                        var v   = model.Mesh.Vertices[ii];
                        var p   = mpos[mposidx[j]];
                        var n   = mnrm[mposidx[j]];
                        p.X     -=v.P.X;
                        p.Y     -=v.P.Y;
                        p.Z     -=v.P.Z;
                        n.X     -=v.N.X;
                        n.Y     -=v.N.Y;
                        n.Z     -=v.N.Z;
                        dic[ii] = new MorphVertex(ii, p.X, p.Y, p.Z, n.X, n.Y, n.Z);
                    }

                    var morph   = new ParamMorph()
                    {
                        Name        = i.Geometry.Name,
                        Vertices    = dic.OrderBy(j => j.Key).Select(j => j.Value).ToList(),
                        NumVertices = dic.Count,
                    };

                    model.Params.Insert(0, morph);
                }
            } else
            {
                throw new Exception();
            }

            ModelFile.ToFile(model.FileName, model);

            System.Diagnostics.Debug.Print("終了");
        }
        public void ReplaceModel(ModelFile model, ModelFile refmodel)
        {
            var vertices= Vertices.Keys.ToList();
            Closest     = vertices.Select(i => FindClosest(refmodel.Mesh.Vertices, i.P)).ToList();

            // スキンの生成
            var sv      = new List<ModelSkin>();

            foreach(var i in Closest)
                sv.Add(refmodel.Mesh.Skins[i]);

            sv      = Closest.Select(i => refmodel.Mesh.Skins[i]).ToList();

            // モーフィングの作成
            var rr      = MorphMax - MorphMin;
            var morphs  = new List<ParamMorph>();

            foreach(var i in refmodel.Params.OfType<ParamMorph>()) // 元のモーフィングを列挙
            {
                var dic     = i.Vertices.ToDictionary(j => j.Index);
                var newmorph= new ParamMorph() {  Vertices= new List<MorphVertex>() };

                System.Diagnostics.Debug.Print("Morph:{0}", i.Name);

                morphs.Add(newmorph);

                for(int j= 0; j < vertices.Count; ++j)
                {
                    var v1  = vertices[j];                          // 新しい頂点
                    var v0  = refmodel.Mesh.Vertices[Closest[j]];   // 元の頂点で一番近いもの
                    var x   = v1.P.X - v0.P.X;
                    var y   = v1.P.Y - v0.P.Y;
                    var z   = v1.P.Z - v0.P.Z;
                    var d   = (float)Math.Sqrt(x*x + y*y + z*z);    // 両頂点の距離

                    // 一定以上離れていたら、モーフィングを引き継がない
                    if(d > MorphMax)
                    {
                      //System.Diagnostics.Debug.Print("  V {0} too far {1:F5}",
                      //    j.ToString().PadLeft(4), d);
                        continue;
                    }

                    MorphVertex mv;

                    // 元の頂点のモーフィングを検索
                    if(!dic.TryGetValue((ushort)Closest[j], out mv))
                    {
                      //System.Diagnostics.Debug.Print("  V {0} => {1} not found",
                      //    j.ToString().PadLeft(4), Closest[j].ToString().PadLeft(4));
                        continue;
                    }

                    // 距離により影響度を算出(MorphMin:1.0 ... MorphMax:0.0)
                    var r   = d <= MorphMin ? 1.0f : 1 - (d - MorphMin) / rr;
                  //r       *=MorphScale;
                  //var n0  = new Vector3(v0.N.X + mv.NX,  v0.N.Y + mv.NY, v0.N.Z + mv.NZ); // 元の頂点のモーフィング後頂点

                  //System.Diagnostics.Debug.Print("  V {0} => {1} dist={2:F5} weight{3:F5}",
                  //    j.ToString().PadLeft(4), Closest[j].ToString().PadLeft(4), d, r);

                    // モーフィング頂点の作成
                    newmorph.Vertices.Add(new MorphVertex()
                    {
                        Index   = (ushort)j,
                        X       = mv.X * r,
                        Y       = mv.Y * r,
                        Z       = mv.Z * r,
                        NX      = mv.NX * r,
                        NY      = mv.NY * r,
                        NZ      = mv.NZ * r,
                      //NX      = (n0.X - v1.N.X) * r,
                      //NY      = (n0.Y - v1.N.Y) * r,
                      //NZ      = (n0.Z - v1.N.Z) * r,
                    });
                }

                System.Diagnostics.Debug.Print("Old={0} New={1}", i.Vertices.Count, newmorph.Vertices.Count);

                newmorph.Name       = i.Name;
                newmorph.NumVertices= newmorph.Vertices.Count;
            }

            // モデルの更新
            model.Mesh.Vertices     = vertices;
            model.Mesh.NumVerts     = vertices.Count;
            model.Mesh.Primitives   = Primitives;
            model.Mesh.NumPrims     = Primitives.Count;
            model.Mesh.Skins        = sv;
            model.Params            = model.Params.Where(i => !(i is ParamMorph)).ToList();
            model.Params.InsertRange(0, morphs.Cast<Param>());
        }