예제 #1
0
        public virtual Operation OnMouseMove(MouseButtons button, PointF point, Matrix transform, SegmentOperation segOp)
        {
            nearestBone  = null;
            nearestPoint = PointF.Empty;

            switch (segOp)
            {
            case SegmentOperation.Segment:
//                    nearestPoint = GetNearestPoint(point, path, 20, transform);
                break;

            case SegmentOperation.Section:
                nearestPoint = GetNearestPoint(point, path, 20, transform);
                break;

            case SegmentOperation.SkeletonAnnotation:
                if (root == null || root.an == null)
                {
                    break;
                }
                nearestBone = root.an.GetNearestBone(point, 20, transform);
                break;

            case SegmentOperation.PartingLine:
                nearestPoint = GetNearestPoint(point, partingLine, 10, transform);
                break;

            default:
                break;
            }
            return(null);
        }
예제 #2
0
        //
        // bone
        //
        private void AssignBoneAnnotation(SkeletonAnnotation an, BoneAnnotation bone, bool record = true)
        {
            if (an == null || bone == null)
            {
                DeleteEditingBone();
                return;
            }

            if (bone.src == bone.dst)
            {
                return;
            }
            if (an.bones.Any(b => b.src == bone.src && b.dst == bone.dst))
            {
                return;
            }
            if (an.bones.Any(b => b.dst == bone.src && b.src == bone.dst))
            {
                return;
            }

            if (record)
            {
                AddOperation(new Operation()
                {
                    funcName   = "AssignBoneAnnotation",
                    parameters = new List <object>()
                    {
                        an, bone,
                    },
                });
            }

            an.bones.Add(bone);
        }
예제 #3
0
        private void CreateOrCompleteEditingBone(SkeletonAnnotation an, JointAnnotation joint)
        {
            if (an == null || joint == null)
            {
                DeleteEditingBone();
                return;
            }

            if (addingBone == null)
            {
                addingBone  = new BoneAnnotation(joint, new JointAnnotation("[dummy]", joint.position));
                selectBone  = null;
                selectJoint = null;
            }
            else
            {
                addingBone.dst = joint;
                if (addingBone.src != addingBone.dst)
                {
                    AssignBoneAnnotation(an, addingBone);
                }
                addingBone  = new BoneAnnotation(joint, new JointAnnotation("[dummy]", joint.position));
                selectBone  = null;
                selectJoint = null;
            }
        }
예제 #4
0
        private void DeleteBoneAnnotation(SkeletonAnnotation an, BoneAnnotation bone, bool record = true)
        {
            if (an == null || bone == null)
            {
                DeleteEditingBone();
                return;
            }

            if (record)
            {
                AddOperation(new Operation()
                {
                    funcName   = "DeleteBoneAnnotation",
                    parameters = new List <object>()
                    {
                        an, bone,
                    },
                });
            }

            for (int i = an.bones.Count - 1; i >= 0; i--)
            {
                if (an.bones[i].src == bone.src && an.bones[i].dst == bone.dst)
                {
                    an.bones.RemoveAt(i);
                }
            }
        }
예제 #5
0
 public ConnectPair(BoneAnnotation bone, SegmentMeshInfo meshInfo1, CharacterRange section1, SegmentMeshInfo meshInfo2, CharacterRange section2)
 {
     this.bone          = bone;
     this.meshInfo1     = meshInfo1;
     this.sectionRange1 = section1;
     this.meshInfo2     = meshInfo2;
     this.sectionRange2 = section2;
 }
예제 #6
0
        void SaveAnnotations(string root, string dirName, Dictionary <string, SkeletonAnnotation> anDict)
        {
            try
            {
                string dir = Path.Combine(root, dirName);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
                foreach (var f in Directory.GetFiles(dir))
                {
                    File.Delete(f);
                }

                List <string> lines = new List <string>();

                for (int i = 0; i < anDict.Count; i++)
                {
                    var    kv = anDict.ElementAt(i);
                    string f  = Path.Combine(dir, kv.Key + ".png");
                    if (kv.Value.bmp != null)
                    {
                        kv.Value.bmp.Save(f);
                    }

                    lines.Add("SkeletonAnnotation[" + kv.Key + "]");

                    for (int j = 0; j < kv.Value.joints.Count; j++)
                    {
                        JointAnnotation joint = kv.Value.joints[j];
                        lines.Add("JointAnnotation[" + j + "]," + joint.name + "," + joint.position.X + "," + joint.position.Y);
                    }
                    for (int j = 0; j < kv.Value.bones.Count; j++)
                    {
                        BoneAnnotation bone = kv.Value.bones[j];
                        if (kv.Value.joints.Contains(bone.src) && kv.Value.joints.Contains(bone.dst))
                        {
                            int srcIdx = kv.Value.joints.IndexOf(bone.src);
                            int dstIdx = kv.Value.joints.IndexOf(bone.dst);
                            lines.Add("BoneAnnotation[" + j + "]," + srcIdx + "," + dstIdx);
                        }
                    }

                    lines.Add("");
                }

                string p = Path.Combine(dir, "skeletonAnnotation.ska");
                File.WriteAllLines(p, lines.ToArray());
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString() + e.StackTrace);
            }
        }
예제 #7
0
 static BoneAnnotation GetBoneAnnotation(SkeletonAnnotation an, BoneAnnotation b)
 {
     if (an == null || b == null || an.bones == null)
     {
         return(null);
     }
     foreach (var bb in an.bones)
     {
         if (b == bb)
         {
             return(bb);
         }
     }
     return(null);
 }
예제 #8
0
        static void GetCoordinateFromBone(BoneAnnotation b, out PointF x, out PointF y)
        {
            x = new PointF(1, 0);
            y = new PointF(0, 1);

            float boneLen = FMath.Distance(b.src.position, b.dst.position);

            if (boneLen <= 1e-4)
            {
                return;
            }

            float dx = (b.dst.position.X - b.src.position.X) / boneLen;
            float dy = (b.dst.position.Y - b.src.position.Y) / boneLen;

            x = new PointF(dx, dy);
            y = new PointF(dy, -dx);
        }
예제 #9
0
        public BoneAnnotation GetNearestBone(PointF point, int threshold, Matrix transform)
        {
            float          minDist = threshold;
            BoneAnnotation bone    = null;

            for (int i = 0; i < bones.Count; i++)
            {
                PointF[] bonePts = new[] { bones[i].src.position, bones[i].dst.position };
                transform.TransformPoints(bonePts);
                float dist = FMath.GetDistanceToLine(point, bonePts[0], bonePts[1]);
                if (dist < minDist)
                {
                    minDist = dist;
                    bone    = bones[i];
                }
            }

            return(bone);
        }
예제 #10
0
        public static void Fitting(SegmentMeshInfo mesh, SkeletonAnnotation refSkeleton)
        {
            mesh.position = Point.Empty;
            mesh.angle    = 0;

            if (mesh.arap == null)
            {
                return;
            }

            Dictionary <BoneAnnotation, List <PointF> > sCps = mesh.boneToControls;

            foreach (var kv in sCps)
            {
                BoneAnnotation b      = kv.Key;
                List <PointF>  orgPts = kv.Value;
                BoneAnnotation br     = GetBoneAnnotation(refSkeleton, b);
                if (br == null)
                {
                    continue;
                }
                if (orgPts.Count <= 1)
                {
                    continue;
                }
                for (int i = 0; i < orgPts.Count; i++)
                {
                    float  t  = (float)i / (orgPts.Count - 1);
                    float  x  = br.src.position.X * (1 - t) + br.dst.position.X * t;
                    float  y  = br.src.position.Y * (1 - t) + br.dst.position.Y * t;
                    PointF?pt = mesh.arap.OrgToCurControlPoint(orgPts[i]);
                    if (pt == null || !pt.HasValue)
                    {
                        continue;
                    }
                    mesh.arap.TranslateControlPoint(pt.Value, new PointF(x, y), false);
                }
            }

            mesh.arap.FlushDefomation();
        }
예제 #11
0
        public bool Equals(BoneAnnotation t)
        {
            if (Object.ReferenceEquals(t, null))
            {
                return(false);
            }
            if (Object.ReferenceEquals(this, t))
            {
                return(true);
            }
            if (this.GetType() != t.GetType())
            {
                return(false);
            }
            if (src == null || dst == null)
            {
                return(false);
            }

            return(src.name == t.src.name && dst.name == t.dst.name);
        }
예제 #12
0
 public void redo_AssignBoneAnnotation(SkeletonAnnotation an, BoneAnnotation bone)
 {
     AssignBoneAnnotation(an, bone, false);
 }
예제 #13
0
        static float GetSectionWidth(List <PointF> path, Tuple <CharacterRange, CharacterRange> curves, BoneAnnotation b)
        {
            float width = 0;
            int   cnt   = Math.Min(curves.Item1.Length, curves.Item2.Length);

            for (int i = 0; i < cnt; i++)
            {
                int idx1 = curves.Item1.First + curves.Item1.Length - 1 - i;
                int idx2 = curves.Item2.First + i;
                while (idx1 < 0)
                {
                    idx1 += path.Count;
                }
                while (idx2 < 0)
                {
                    idx2 += path.Count;
                }
                PointF pt1 = path[idx1 % path.Count];
                PointF pt2 = path[idx2 % path.Count];
                PointF pt  = new PointF(pt2.X - pt1.X + b.src.position.X, pt2.Y - pt1.Y + b.src.position.Y);
                width += FMath.GetDistanceToLine(pt, b.src.position, b.dst.position, false);
            }
            width /= cnt;
            return(width);
        }
예제 #14
0
        static float GetSectionHeight(List <PointF> path, Tuple <CharacterRange, CharacterRange> curves, BoneAnnotation b)
        {
            if (path == null || curves == null || b == null)
            {
                return(0);
            }

            if (curves.Item1 == null || curves.Item2 == null)
            {
                return(0);
            }

            float height = 0;

            float boneLen = FMath.Distance(b.src.position, b.dst.position);

            if (boneLen <= 1e-4)
            {
                return(0);
            }

            PointF x, y;

            GetCoordinateFromBone(b, out x, out y);

            // 各セグメントのボーンからのズレを求める
            int cnt = Math.Min(curves.Item1.Length, curves.Item2.Length);

            for (int i = 0; i < cnt; i++)
            {
                int idx1 = curves.Item1.First + curves.Item1.Length - 1 - i;
                int idx2 = curves.Item2.First + i;
                while (idx1 < 0)
                {
                    idx1 += path.Count;
                }
                while (idx2 < 0)
                {
                    idx2 += path.Count;
                }
                PointF pt1 = path[idx1 % path.Count];
                PointF pt2 = path[idx2 % path.Count];
                pt1.X  -= b.src.position.X;
                pt1.Y  -= b.src.position.Y;
                pt2.X  -= b.src.position.X;
                pt2.Y  -= b.src.position.Y;
                height += pt1.X * y.X + pt1.Y * y.Y;
                height += pt2.X * y.X + pt2.Y * y.Y;
            }

            height /= 2 * cnt;

            return(height);
        }
예제 #15
0
        // 接合面に近づく向きに曲線の点をついかする
        static List <List <PointF> > GetSortedCurves(List <PointF> path, Tuple <CharacterRange, CharacterRange> ranges, BoneAnnotation baseBone)
        {
            List <List <PointF> > curves = new List <List <PointF> >();

            foreach (var range in new[] { ranges.Item1, ranges.Item2 })
            {
                var ls = new List <PointF>();
                for (int i = range.First; i < range.First + range.Length; i++)
                {
                    ls.Add(path[Rem(i, path.Count)]);
                }
                curves.Add(ls);
            }

            // 向きを揃える
            curves[1].Reverse();

            // ボーンに対する位置関係を揃える
            PointF pt = path[Rem(ranges.Item2.First, path.Count)];

            if (FMath.GetSide(pt, baseBone.src.position, baseBone.dst.position) < 0)
            {
                var ls = curves[0];
                curves[0] = curves[1];
                curves[1] = ls;
            }

            return(curves);
        }
예제 #16
0
 private void SelectBoneAnnotation(SkeletonAnnotation an, BoneAnnotation boneAnnotation)
 {
     addingBone  = null;
     selectBone  = an.bones.Contains(boneAnnotation) ? boneAnnotation : null;
     selectJoint = null;
 }
예제 #17
0
 public void undo_DeleteBoneAnnotation(SkeletonAnnotation an, BoneAnnotation bone)
 {
     AssignBoneAnnotation(an, bone, false);
 }
예제 #18
0
 public void redo_DeleteBoneAnnotation(SkeletonAnnotation an, BoneAnnotation bone)
 {
     DeleteBoneAnnotation(an, bone, false);
 }
예제 #19
0
        public virtual Operation OnMouseDown(MouseButtons button, PointF point, Matrix transform, SegmentOperation segOp)
        {
            PointF nearest;

            switch (segOp)
            {
            case SegmentOperation.Segment:
                break;

            case SegmentOperation.Section:
                if (button != MouseButtons.Left)
                {
                    break;
                }
                nearest = GetNearestPoint(point, path, 20, transform);
                if (nearest.IsEmpty)
                {
                    break;
                }
                if (!section.Contains(nearest))
                {
                    section.Add(nearest);
                }
                else
                {
                    section.Remove(nearest);
                }
                break;

            case SegmentOperation.SkeletonAnnotation:
                if (button != MouseButtons.Left)
                {
                    break;
                }
                if (root == null || root.an == null)
                {
                    break;
                }
                BoneAnnotation nearBone = root.an.GetNearestBone(point, 20, transform);
                if (nearBone == null)
                {
                    break;
                }
                if (!an.bones.Contains(nearBone))
                {
                    an.bones.Add(nearBone);
                }
                else
                {
                    an.bones.Remove(nearBone);
                }
                an.joints.Clear();
                foreach (var bone in an.bones)
                {
                    if (!an.joints.Contains(bone.src))
                    {
                        an.joints.Add(bone.src);
                    }
                    if (!an.joints.Contains(bone.dst))
                    {
                        an.joints.Add(bone.dst);
                    }
                }
                break;

            case SegmentOperation.PartingLine:
                if (button != MouseButtons.Left)
                {
                    break;
                }
                nearest = GetNearestPoint(point, partingLine, 10, transform);
                if (nearest.IsEmpty)
                {
                    partingLine.Add(InvertPoint(point, transform));
                }
                else
                {
                    partingLine.Remove(nearest);
                }
                break;

            default:
                break;
            }
            return(null);
        }
예제 #20
0
 public int dir; // boneのセグメントからの露出方向。1ならsrc -> dst。-1ならdst -> src
 public CrossBoneSection(BoneAnnotation bone, CharacterRange sectionRange, int dir)
 {
     this.bone         = bone;
     this.sectionRange = sectionRange;
     this.dir          = dir;
 }
예제 #21
0
 static bool AreEqualBone(BoneAnnotation b1, BoneAnnotation b2)
 {
     return((b1.src.name == b2.src.name && b1.dst.name == b2.dst.name) ||
            (b1.src.name == b2.dst.name && b1.dst.name == b2.src.name));
 }