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> >(); }
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 static ARAPDeformation Combine(ARAPDeformation arap1, ARAPDeformation arap2, CharacterRange sectionRange1, CharacterRange sectionRange2) { var arap = new ARAPDeformation(); // パスの統合 var path1 = arap1.GetPath(); var path2 = arap2.GetPath(); var path = CombinePath(path1, path2, sectionRange1, sectionRange2); // メッシュの統合 CombineMesh(arap1, arap2, path, arap); // partの統合。接合面付近のpartを同じにする throw new NotImplementedException(); }
public ARAPDeformation(ARAPDeformation aRAPDeformation) { if (aRAPDeformation == null) { return; } orgMeshPointList = new List <PointF>(aRAPDeformation.orgMeshPointList); texcoordList = new List <PointF>(aRAPDeformation.texcoordList); meshPointList = new List <PointF>(aRAPDeformation.meshPointList); meshList = new List <TriMesh>(aRAPDeformation.meshList); pathCnt = aRAPDeformation.pathCnt; controls = new List <PointF>(aRAPDeformation.controls); orgControls = new List <PointF>(aRAPDeformation.orgControls); meshPtToPart = new List <int>(aRAPDeformation.meshPtToPart); controlsToPart = new List <int>(aRAPDeformation.controlsToPart); if (aRAPDeformation.weights != null) { weights = aRAPDeformation.weights.ToArray(); } if (aRAPDeformation.A00 != null) { A00 = aRAPDeformation.A00.ToArray(); } if (aRAPDeformation.A01 != null) { A01 = aRAPDeformation.A01.ToArray(); } if (aRAPDeformation.A10 != null) { A10 = aRAPDeformation.A10.ToArray(); } if (aRAPDeformation.A11 != null) { A11 = aRAPDeformation.A11.ToArray(); } if (aRAPDeformation.D != null) { D = aRAPDeformation.D.ToArray(); } }
public static void SetPathControlPoints(ARAPDeformation arap) { if (arap == null) { return; } arap.ClearControlPoints(); var path = arap.GetPath(); if (path == null) { return; } for (int i = 0; i < path.Count; i++) { arap.AddControlPoint(arap.meshPointList[i], arap.orgMeshPointList[i]); } }
public static void SetSkeletalControlPoints(ARAPDeformation arap, SkeletonAnnotation an, int linearSpan, Dictionary <BoneAnnotation, List <PointF> > boneToControls) { if (arap == null) { return; } boneToControls.Clear(); arap.ClearControlPoints(); // ボーン沿いに制御点を追加 HashSet <PointF> pts = new HashSet <PointF>(); if (an != null && linearSpan >= 1) { foreach (var b in an.bones) { PointF p0 = b.src.position; PointF p1 = b.dst.position; float dist = FMath.Distance(p0, p1); int ptNum = Math.Max(2, (int)(dist / linearSpan) + 1); boneToControls[b] = new List <PointF>(); for (int i = 0; i < ptNum; i++) { float t = (float)i / (ptNum - 1); PointF p = i == 0 ? p0 : i == ptNum - 1 ? p1 : FMath.Interpolate(p0, p1, t); if (!pts.Contains(p)) { arap.AddControlPoint(p, p); } boneToControls[b].Add(p); pts.Add(p); } } } }
private static void CombineMesh(ARAPDeformation arap1, ARAPDeformation arap2, List <PointF> path, ARAPDeformation outArap) { // 点群の統合 // meshPointListは現在の値で、orgMeshPointList = meshPointListと再初期化 outArap.pathCnt = path.Count; outArap.meshPointList = new List <PointF>(); Dictionary <PointF, int> ptToIdx = new Dictionary <PointF, int>(); int idx = 0; foreach (var ls in new[] { path, arap1.meshPointList, arap2.meshPointList }) { foreach (var p in ls) { if (!ptToIdx.ContainsKey(p)) { continue; } outArap.meshPointList.Add(p); ptToIdx[p] = idx; idx++; } } outArap.orgMeshPointList = new List <PointF>(outArap.meshPointList); // 三角形の統合 outArap.meshList = new List <TriMesh>(); // outArap.meshList.Add(new TriMesh( // texcoordはそのまま }
public SegmentMeshInfo(Segment seg, bool initControlPoints) { if (seg == null) { return; } if (seg.path != null && seg.path.Count > 3) { // メッシュを生成 var shiftPath = ShiftPath(seg.path, -seg.offset.X, -seg.offset.Y); var sdPath = PathSubdivision.Subdivide(shiftPath, 10); sdPath.RemoveAt(sdPath.Count - 1); // 終点(始点と同じ)は消す var partingLine = new List <PointF>(); if (seg.partingLine != null) { partingLine = ShiftPath(seg.partingLine, -seg.offset.X, -seg.offset.Y); } arap = new ARAPDeformation(sdPath, partingLine); // 接合面の情報をコピー if (seg.section != null || seg.section.Count > 0) { var _sections = FMath.SplitPathRange(ShiftPath(seg.section, -seg.offset.X, -seg.offset.Y), shiftPath, true); sections = new List <CharacterRange>(); foreach (var r in _sections) { int i1 = r.First; int i2 = r.First + r.Length - 1; try { int j1 = sdPath.IndexOf(shiftPath[i1]); int j2 = sdPath.IndexOf(shiftPath[i2]); sections.Add(new CharacterRange(j1, j2 - j1 + 1)); } catch (Exception e) { Console.WriteLine(e + e.StackTrace); } } } } if (seg.an != null) { // スケルトンをコピー an = new SkeletonAnnotation(seg.an, false); foreach (var j in an.joints) { j.position = new PointF(j.position.X - seg.offset.X, j.position.Y - seg.offset.Y); } } // 接合面とボーンの交差情報 if (sections != null && sections.Count >= 1 && seg.an != null && seg.an.bones != null) { crossDict = GetBoneSectionCrossDict(GetPath(), sections, an); } if (initControlPoints && arap != null) { // 制御点を初期 InitializeControlPoints(arap, an, 30, sections, boneToControls); arap.BeginDeformation(); } }
static void InitializeControlPoints(ARAPDeformation arap, SkeletonAnnotation an, int linearSpan, List <CharacterRange> sections, Dictionary <BoneAnnotation, List <PointF> > boneToControls) { SetSkeletalControlPoints(arap, an, linearSpan, boneToControls); }
private static void ExpandSegments(List <SegmentMeshInfo> meshes, SkeletonAnnotation an, List <ConnectPair> pairs) { int _cnt = 0; foreach (var m in meshes) { if (m.arap == null) { continue; } m.arap.controlPoints.Clear(); SegmentMeshInfo.SetPathControlPoints(m.arap); m.arap.BeginDeformation(); m.arap.ToBitmap().Save("../../../Test2/" + (_cnt++) + ".png"); } 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 ranges1 = SectionToCurves(path1, p.sectionRange1, 5, 30); var ranges2 = SectionToCurves(path2, p.sectionRange2, 5, 30); if (ranges1 == null || ranges2 == null) { continue; } var curves1 = GetSortedCurves(path1, ranges1, b); var curves2 = GetSortedCurves(path2, ranges2, b); if (curves1.Count != 2 || curves2.Count != 2) { continue; } List <Tuple <PointF, PointF> > move1 = new List <Tuple <PointF, PointF> >(); List <Tuple <PointF, PointF> > move2 = new List <Tuple <PointF, PointF> >(); for (int i = 0; i < 2; i++) { var p1 = curves1[i].First(); var v1 = new PointF(p1.X - curves1[i].Last().X, p1.Y - curves1[i].Last().Y); var p2 = curves2[i].First(); var v2 = new PointF(curves2[i].Last().X - p2.X, curves2[i].Last().Y - p2.Y); // 2点かぶらせる int cnt = curves1[i].Count + curves2[i].Count - 2; if (cnt <= 1) { continue; } for (int j = 0; j < curves1[i].Count; j++) { PointF to = FMath.HelmitteInterporate(p1, v1, p2, v2, (float)j / (cnt - 1)); if (j == curves1[i].Count - 1) { move1.Add(new Tuple <PointF, PointF>(curves1[i][j], to)); } m1.arap.TranslateControlPoint(curves1[i][j], to, false); } for (int j = 0; j < curves2[i].Count; j++) { PointF to = FMath.HelmitteInterporate(p1, v1, p2, v2, (float)(-j + cnt - 1) / (cnt - 1)); if (j == curves2[i].Count - 1) { move2.Add(new Tuple <PointF, PointF>(curves2[i][j], to)); } m2.arap.TranslateControlPoint(curves2[i][j], to, false); } } List <PointF> sections1 = new List <PointF>(); List <PointF> sections2 = new List <PointF>(); for (int i = p.sectionRange1.First + 1; i < p.sectionRange1.First + p.sectionRange1.Length - 1; i++) { sections1.Add(path1[Rem(i, path1.Count)]); } for (int i = p.sectionRange2.First + 1; i < p.sectionRange2.First + p.sectionRange2.Length - 1; i++) { sections2.Add(path2[Rem(i, path2.Count)]); } List <PointF> newSection1 = ARAPDeformation.Deform(sections1, move1); List <PointF> newSection2 = ARAPDeformation.Deform(sections2, move2); if (newSection1.Count == sections1.Count) { for (int i = 0; i < newSection1.Count; i++) { m1.arap.TranslateControlPoint(sections1[i], newSection1[i], false); } } if (newSection2.Count == sections2.Count) { for (int i = 0; i < newSection2.Count; i++) { m2.arap.TranslateControlPoint(sections2[i], newSection2[i], false); } } m1.arap.FlushDefomation(); m2.arap.FlushDefomation(); } } foreach (var m in meshes) { if (m.arap == null) { continue; } m.arap.EndDeformation(); } }