Пример #1
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);
                }
            }
        }
Пример #2
0
 public void Initialize(Bitmap bmp)
 {
     an           = new SkeletonAnnotation(bmp);
     selectJoint  = null;
     nearestJoint = null;
     transform    = new Matrix();
 }
Пример #3
0
        static List <ConnectPair> GetSectionPairs(List <SegmentMeshInfo> meshes, SkeletonAnnotation an)
        {
            if (an == null)
            {
                return(null);
            }

            if (meshes == null)
            {
                return(null);
            }

            var pairs = new List <ConnectPair>();

            foreach (var b in an.bones)
            {
                var crosses = new Dictionary <SegmentMeshInfo, CrossBoneSection>();
                foreach (var m in meshes)
                {
                    if (m.crossDict.ContainsKey(b))
                    {
                        crosses[m] = m.crossDict[b];
                    }
                }

                if (crosses.Count == 2 && crosses.Values.First().dir *crosses.Values.Last().dir < 0)
                {
                    var kv1 = crosses.First();
                    var kv2 = crosses.Last();
                    pairs.Add(new ConnectPair(b, kv1.Key, kv1.Value.sectionRange, kv2.Key, kv2.Value.sectionRange));
                }
            }

            return(pairs);
        }
Пример #4
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;
            }
        }
Пример #5
0
        public SkeletonAnnotation(SkeletonAnnotation an, bool copyBmp)
        {
            if (an == null)
            {
                return;
            }

            if (copyBmp && an.bmp != null)
            {
                this.bmp = new Bitmap(an.bmp);
            }

            this.joints = new List <JointAnnotation>();
            foreach (var j in an.joints)
            {
                this.joints.Add(new JointAnnotation(j.name, j.position));
            }

            this.bones = new List <BoneAnnotation>();
            foreach (var b in an.bones)
            {
                if (!an.joints.Contains(b.src) || !an.joints.Contains(b.dst))
                {
                    continue;
                }
                int idx0 = an.joints.IndexOf(b.src);
                int idx1 = an.joints.IndexOf(b.dst);
                this.bones.Add(new BoneAnnotation(this.joints[idx0], this.joints[idx1]));
            }
        }
Пример #6
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);
        }
Пример #7
0
        //
        // joint
        //
        private void AssignJointAnnotation(SkeletonAnnotation an, JointAnnotation joint, bool record = true)
        {
            if (an == null || joint == null)
            {
                DeleteEditingBone();
                return;
            }

            if (an.joints.Any(j => j.name == joint.name && j.position == joint.position))
            {
                return;
            }

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

            an.joints.Add(joint);
        }
Пример #8
0
        private void skeletonFittingCanvas_MouseDown(object sender, MouseEventArgs e)
        {
            SkeletonAnnotation an = GetEditingAnnotation();

            if (an == null)
            {
                return;
            }

            PointF convLocation = InvertCoordinate(e.Location, skeletonFittingCanvasTransform);

            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                // joint
                if (jointAddRadioButton.Checked)
                {
                    AssignJointAnnotation(an, new JointAnnotation(jointNameTextBox.Text, convLocation));
                }

                if (jointSelectRadioButton.Checked)
                {
                    JointAnnotation joint = an.GetNearestJoint(e.Location, 20, skeletonFittingCanvasTransform);
                    SelectJointAnnotation(an, joint);
                    if (joint != null)
                    {
                        jointNameTextBox.Text = joint.name;
                    }
                }

                // bone
                if (boneAddRadioButton.Checked)
                {
                    var joint = an.GetNearestJoint(e.Location, 20, skeletonFittingCanvasTransform);
                    if (joint != null)
                    {
                        CreateOrCompleteEditingBone(an, joint);
                    }
                    else
                    {
                        DeleteEditingBone();
                    }
                }

                if (boneSelectRadioButton.Checked)
                {
                    SelectBoneAnnotation(an, an.GetNearestBone(e.Location, 20, skeletonFittingCanvasTransform));
                }

                skeletonFittingCanvas.Invalidate();
            }

            // 画像をずらす
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (tabControl.SelectedTab.Name == "tabSkeletonFitting")
                {
                    skeletonFittingCanvasPrevMousePos = e.Location;
                }
            }
        }
Пример #9
0
        static Dictionary <BoneAnnotation, Matrix> GetSkeletalTransforms(SkeletonAnnotation an, SkeletonAnnotation orgAn)
        {
            Dictionary <BoneAnnotation, Matrix> transformDict = new Dictionary <BoneAnnotation, Matrix>();

            for (int i = 0; i < an.bones.Count; i++)
            {
                var b  = an.bones[i];
                var ob = orgAn.bones[i];

                float angle1 = (float)Math.Atan2(ob.dst.position.Y - ob.src.position.Y, ob.dst.position.X - ob.src.position.X);
                float angle2 = (float)Math.Atan2(b.dst.position.Y - b.src.position.Y, b.dst.position.X - b.src.position.X);
                angle1 = FMath.ToDegree(angle1);
                angle2 = FMath.ToDegree(angle2);

                float len1 = FMath.Distance(ob.src.position, ob.dst.position);
                float len2 = FMath.Distance(b.src.position, b.dst.position);

                if (len1 <= 1e-4)
                {
                    transformDict[b] = new Matrix();
                    continue;
                }

                Matrix transform = new Matrix();
                transform.Translate(-ob.src.position.X, -ob.src.position.Y, MatrixOrder.Append);
                transform.Rotate(-angle1, MatrixOrder.Append);
                transform.Scale(len2 / len1, len2 / len1, MatrixOrder.Append);
                transform.Rotate(angle2, MatrixOrder.Append);
                transform.Translate(b.src.position.X, b.src.position.Y, MatrixOrder.Append);

                transformDict[b] = transform;
            }

            return(transformDict);
        }
Пример #10
0
        static BoneAnnotation GetCrossingBoneWithPath(SkeletonAnnotation an, List <PointF> section)
        {
            if (an == null || an.bones == null)
            {
                return(null);
            }
            if (section == null)
            {
                return(null);
            }

            foreach (var b in an.bones)
            {
                PointF p0 = b.src.position;
                PointF p1 = b.dst.position;
                for (int i = 0; i < section.Count - 1; i++)
                {
                    if (FMath.IsCrossed(p0, p1, section[i], section[i + 1]))
                    {
                        return(b);
                    }
                }
            }

            return(null);
        }
Пример #11
0
        public SegmentMeshInfo(List <SegmentMeshInfo> list, SkeletonAnnotation an)
        {
            position = Point.Empty;
            angle    = 0;
            scale    = Point.Empty;
            reverse  = false;

            arap = null; // TODO  ARAPDeformation.Combine();

            Dictionary <BoneAnnotation, CrossBoneSection> crossDict = new Dictionary <BoneAnnotation, CrossBoneSection>();

            foreach (var m in list)
            {
                foreach (var kv in m.crossDict)
                {
                    if (!crossDict.ContainsKey(kv.Key))
                    {
                        crossDict[kv.Key] = kv.Value;
                    }
                    else
                    {
                        crossDict.Remove(kv.Key);
                    }
                }
            }

            sections = crossDict.Values.Select(c => c.sectionRange).ToList();

            this.an        = new SkeletonAnnotation(an, true);
            boneToControls = new Dictionary <BoneAnnotation, List <PointF> >();
        }
Пример #12
0
        //----------------------------------------------------------------------
        // Tab:Skeleton Fitting
        //----------------------------------------------------------------------

        void SetEditingAnnotation(string key, bool record = true)
        {
            if (sourceImageDict.ContainsKey(key))
            {
                if (record)
                {
                    AddOperation(new Operation()
                    {
                        funcName   = "SetEditingAnnotation",
                        parameters = new List <object>()
                        {
                            editingAnnotationKey,
                            key,
                        }
                    });
                }

                if (skeletonAnnotationDict.ContainsKey(key))
                {
                    if (skeletonAnnotationDict[key].bmp != null)
                    {
                        skeletonAnnotationDict[key].bmp.Dispose();
                    }
                    skeletonAnnotationDict[key].bmp = new Bitmap(sourceImageDict[key]);
                }
                else
                {
                    skeletonAnnotationDict[key] = new SkeletonAnnotation(new Bitmap(sourceImageDict[key]));
                }
                editingAnnotationKey = key;
            }
        }
Пример #13
0
        void DrawSkeleton(SkeletonAnnotation skeleton, Dictionary <JointAnnotation, XNAColor> highlight, XNAColor defaultColor)
        {
            int lineNum = SkeletonToLineList(skeleton, XNAColor.Red, vertexList);

            if (lineNum <= 0)
            {
                return;
            }

            bool succeed = FlushVertexList(vertexList, true, false, null);

            if (!succeed)
            {
                return;
            }

            DrawLineList(lineNum);

            for (int i = 0; i < skeleton.joints.Count; i++)
            {
                if (highlight.ContainsKey(skeleton.joints[i]))
                {
                    DrawPoint((int)skeleton.joints[i].position.X, (int)skeleton.joints[i].position.Y, highlight[skeleton.joints[i]], 10);
                }
                else
                {
                    DrawPoint((int)skeleton.joints[i].position.X, (int)skeleton.joints[i].position.Y, defaultColor, 10);
                }
            }
        }
Пример #14
0
 public void undo_DeleteJointAnnotation(SkeletonAnnotation an, JointAnnotation joint, List <BoneAnnotation> bones)
 {
     AssignJointAnnotation(an, joint, false);
     foreach (var bone in bones)
     {
         AssignBoneAnnotation(an, bone, false);
     }
 }
Пример #15
0
        public void AssignSegmentRootAs(string name, Bitmap bmp, SkeletonAnnotation an)
        {
            var root = new SegmentRoot(bmp, an);

            if (segmentRootDict.ContainsKey(name))
            {
                segmentRootDict[name].Dispose();
            }
            segmentRootDict[name] = root;
        }
Пример #16
0
 public Composition(string refSkeletonPath)
 {
     transform   = new Matrix();
     editingUnit = new ComposedUnit();
     an          = SkeletonAnnotation.Load(refSkeletonPath, null);
     if (an == null)
     {
         an = new SkeletonAnnotation(null);
     }
 }
Пример #17
0
 public SegmentRoot(Bitmap bmp, SkeletonAnnotation an)
 {
     if (bmp != null)
     {
         this.bmp = new Bitmap(bmp);
     }
     this.an = an;
     segments.Add(new Segment("Full", this)
     {
         bmp = this.bmp,
     });
 }
Пример #18
0
        public static SkeletonAnnotation OpenRefSkeleton(string filepath, Bitmap refSkeletonBmp)
        {
            filepath = Path.GetFullPath(filepath);
            string root = Path.GetDirectoryName(filepath);

            if (!File.Exists(filepath))
            {
                return(null);
            }

            return(SkeletonAnnotation.Load(filepath, refSkeletonBmp));
        }
Пример #19
0
 private void UpdateEditingBone(SkeletonAnnotation an, JointAnnotation joint)
 {
     if (an == null || joint == null)
     {
         DeleteEditingBone();
         return;
     }
     if (addingBone != null)
     {
         addingBone.dst = joint;
     }
 }
Пример #20
0
        public void UpdateSkeletalControlPoints(SkeletonAnnotation refAnnotation)
        {
            if (an == null)
            {
                return;
            }

            if (arap == null)
            {
                return;
            }

            var orgAn = new SkeletonAnnotation(an, false);

            foreach (var j in an.joints)
            {
                foreach (var jr in refAnnotation.joints)
                {
                    if (j.name == jr.name)
                    {
                        j.position = jr.position;
                        break;
                    }
                }
            }

            var transformDict = GetSkeletalTransforms(an, orgAn);

            foreach (var kv in boneToControls)
            {
                if (kv.Value == null || kv.Value.Count <= 0)
                {
                    continue;
                }
                var bone = kv.Key;
                foreach (var orgPt in kv.Value)
                {
                    if (!transformDict.ContainsKey(bone))
                    {
                        continue;
                    }
                    var transform = transformDict[bone];
                    var pt        = arap.OrgToCurControlPoint(orgPt);
                    if (pt == null)
                    {
                        continue;
                    }
                    var to = FMath.Transform(pt.Value, transform);
                    arap.TranslateControlPoint(pt.Value, to, false);
                }
            }
        }
Пример #21
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);
 }
Пример #22
0
 private void skeletonFittingCanvas_MouseClick(object sender, MouseEventArgs e)
 {
     if (e.Button == System.Windows.Forms.MouseButtons.Right)
     {
         SkeletonAnnotation an = GetEditingAnnotation();
         if (jointSelectRadioButton.Checked || jointAddRadioButton.Checked)
         {
             DeleteJointAnnotation(an, an.GetNearestJoint(e.Location, 20, skeletonFittingCanvasTransform));
         }
         if (boneSelectRadioButton.Checked || boneAddRadioButton.Checked)
         {
             DeleteBoneAnnotation(an, an.GetNearestBone(e.Location, 20, skeletonFittingCanvasTransform));
         }
     }
 }
Пример #23
0
        public SegmentMeshInfo(SegmentMeshInfo m)
        {
            position = m.position;
            angle    = m.angle;
            scale    = m.scale;
            reverse  = m.reverse;

            arap = new ARAPDeformation(m.arap);

            sections = new List <CharacterRange>(m.sections);

            an = new SkeletonAnnotation(m.an, true);

            boneToControls = new Dictionary <BoneAnnotation, List <PointF> >(m.boneToControls);
            crossDict      = new Dictionary <BoneAnnotation, CrossBoneSection>(m.crossDict);
        }
Пример #24
0
        public Segment(Segment seg, string name = "")
        {
            if (seg == null)
            {
                return;
            }

            this.name        = name == "" ? seg.name : name;
            this.bmp         = seg.bmp == null ? null : new Bitmap(seg.bmp);
            this.offset      = seg.offset;
            this.root        = null;
            this.an          = new SkeletonAnnotation(seg.an, false);
            this.section     = new List <PointF>(seg.section);
            this.partingLine = new List <PointF>(seg.partingLine);
            this.path        = new List <PointF>(seg.path);
        }
Пример #25
0
        static float AdjustScale(List <SegmentMeshInfo> meshes, SkeletonAnnotation an, List <ConnectPair> pairs)
        {
            float delta = 0;

            // ボーンのsrc側のセグメントの接合面の幅にdst側のセグメントの幅を揃える
            foreach (var b in an.bones)
            {
                foreach (var p in pairs)
                {
                    if (p.bone != b)
                    {
                        continue;
                    }
                    var m1 = p.meshInfo1;
                    var m2 = p.meshInfo2;
                    if (m1.arap == null || m2.arap == null)
                    {
                        continue;
                    }

                    var path1 = m1.arap.GetPath();
                    var path2 = m2.arap.GetPath();

                    var curves1 = SectionToCurves(path1, p.sectionRange1, 5, 30);
                    var curves2 = SectionToCurves(path2, p.sectionRange2, 5, 30);
                    if (curves1 == null || curves2 == null)
                    {
                        continue;
                    }

                    float width1 = GetSectionWidth(path1, curves1, b);
                    float width2 = GetSectionWidth(path2, curves2, b);

                    // サイズを合わせる
                    if (Math.Abs(width1 - width2) > 1e-4)
                    {
                        m2.Scale(width1 / width2, width1 / width2);
                    }

                    delta += width1 * width1 / (width2 * width2);
                }
            }

            return(delta);
        }
Пример #26
0
        JointAnnotation GetNearestJoint(SkeletonAnnotation an, PointF point, float threshold, CompositionCanvasControl canvas)
        {
            JointAnnotation nearest   = null;
            float           minSqDist = threshold * threshold;

            foreach (var joint in an.joints)
            {
                PointF pt     = canvas.PointToClient(new Point((int)joint.position.X, (int)joint.position.Y));
                float  dx     = point.X - pt.X;
                float  dy     = point.Y - pt.Y;
                float  sqDist = dx * dx + dy * dy;
                if (minSqDist > sqDist)
                {
                    nearest   = joint;
                    minSqDist = sqDist;
                }
            }
            return(nearest);
        }
Пример #27
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();
        }
Пример #28
0
        private static void AdjustPosition(List <SegmentMeshInfo> meshes, SkeletonAnnotation an, List <ConnectPair> pairs)
        {
            foreach (var b in an.bones)
            {
                foreach (var p in pairs)
                {
                    if (p.bone != b)
                    {
                        continue;
                    }
                    var m1 = p.meshInfo1;
                    var m2 = p.meshInfo2;
                    if (m1.arap == null || m2.arap == null)
                    {
                        continue;
                    }
                    var path1   = m1.arap.GetPath();
                    var path2   = m2.arap.GetPath();
                    var curves1 = SectionToCurves(path1, p.sectionRange1, 5, 30);
                    var curves2 = SectionToCurves(path2, p.sectionRange2, 5, 30);
                    if (curves1 == null || curves2 == null)
                    {
                        continue;
                    }

                    float height1 = GetSectionHeight(path1, curves1, b);
                    float height2 = GetSectionHeight(path2, curves2, b);

                    PointF x, y;
                    GetCoordinateFromBone(b, out x, out y);

                    // サイズを合わせる
                    if (Math.Abs(height1 - height2) > 1e-4)
                    {
                        m2.Translate(y.X * (height1 - height2), y.Y * (height1 - height2));
                    }
                }
            }
        }
Пример #29
0
        private void skeletonFittingCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            SkeletonAnnotation an = GetEditingAnnotation();

            if (an == null)
            {
                return;
            }

            if (jointSelectRadioButton.Checked || jointAddRadioButton.Checked || boneAddRadioButton.Checked)
            {
                nearestJoint = an.GetNearestJoint(e.Location, 20, skeletonFittingCanvasTransform);
            }
            if (boneSelectRadioButton.Checked || boneAddRadioButton.Checked)
            {
                nearestBone = an.GetNearestBone(e.Location, 20, skeletonFittingCanvasTransform);
            }

            PointF convLocation = InvertCoordinate(e.Location, skeletonFittingCanvasTransform);

            if (addingBone != null)
            {
                UpdateEditingBone(an, new JointAnnotation("[dummy]", convLocation));
            }

            skeletonFittingCanvas.Invalidate();

            // 画像をずらす
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (tabControl.SelectedTab.Name == "tabSkeletonFitting")
                {
                    PointF pos = e.Location;
                    skeletonFittingCanvasPan(pos.X - skeletonFittingCanvasPrevMousePos.X, pos.Y - skeletonFittingCanvasPrevMousePos.Y);
                    skeletonFittingCanvasPrevMousePos = pos;
                }
            }
        }
Пример #30
0
        private void DeleteJointAnnotation(SkeletonAnnotation an, JointAnnotation joint, bool record = true)
        {
            if (an == null || joint == null)
            {
                DeleteEditingBone();
                return;
            }

            if (record)
            {
                AddOperation(new Operation()
                {
                    funcName   = "DeleteJointAnnotation",
                    parameters = new List <object>()
                    {
                        an, joint, new List <BoneAnnotation>(an.bones)
                    },
                });
            }

            // 関連するボーンを削除
            for (int i = an.bones.Count - 1; i >= 0; i--)
            {
                if ((an.bones[i].src.name == joint.name && an.bones[i].src.position == joint.position) ||
                    (an.bones[i].dst.name == joint.name && an.bones[i].dst.position == joint.position))
                {
                    an.bones.RemoveAt(i);
                }
            }
            // 関節を削除
            for (int i = an.joints.Count - 1; i >= 0; i--)
            {
                if (an.joints[i].name == joint.name && an.joints[i].position == joint.position)
                {
                    an.joints.RemoveAt(i);
                }
            }
        }