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); }
// // 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); }
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; } }
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); } } }
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; }
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); } }
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); }
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); }
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); }
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(); }
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); }
public void redo_AssignBoneAnnotation(SkeletonAnnotation an, BoneAnnotation bone) { AssignBoneAnnotation(an, bone, false); }
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); }
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); }
// 接合面に近づく向きに曲線の点をついかする 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); }
private void SelectBoneAnnotation(SkeletonAnnotation an, BoneAnnotation boneAnnotation) { addingBone = null; selectBone = an.bones.Contains(boneAnnotation) ? boneAnnotation : null; selectJoint = null; }
public void undo_DeleteBoneAnnotation(SkeletonAnnotation an, BoneAnnotation bone) { AssignBoneAnnotation(an, bone, false); }
public void redo_DeleteBoneAnnotation(SkeletonAnnotation an, BoneAnnotation bone) { DeleteBoneAnnotation(an, bone, false); }
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); }
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; }
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)); }