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 void Initialize(Bitmap bmp) { an = new SkeletonAnnotation(bmp); selectJoint = null; nearestJoint = null; transform = new Matrix(); }
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); }
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; } }
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])); } }
// // 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); }
// // 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); }
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; } } }
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); }
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); }
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> >(); }
//---------------------------------------------------------------------- // 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; } }
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); } } }
public void undo_DeleteJointAnnotation(SkeletonAnnotation an, JointAnnotation joint, List <BoneAnnotation> bones) { AssignJointAnnotation(an, joint, false); foreach (var bone in bones) { AssignBoneAnnotation(an, bone, false); } }
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; }
public Composition(string refSkeletonPath) { transform = new Matrix(); editingUnit = new ComposedUnit(); an = SkeletonAnnotation.Load(refSkeletonPath, null); if (an == null) { an = new SkeletonAnnotation(null); } }
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, }); }
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)); }
private void UpdateEditingBone(SkeletonAnnotation an, JointAnnotation joint) { if (an == null || joint == null) { DeleteEditingBone(); return; } if (addingBone != null) { addingBone.dst = joint; } }
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); } } }
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); }
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)); } } }
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); }
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); }
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); }
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); }
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(); }
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)); } } } }
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; } } }
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); } } }