public MainPlugin() { SkeletonForm f = null; CreateBonePointInfo createBonePointInfo = null; Tuple <int, int>[] anchorSelect = null; this.Initialize += (sender, e) => { f = new SkeletonForm(); f.ModeChanged += (sender2, e2) => { createBonePointInfo = null; Plugin.RefreshView(); }; f.CreateAnchor += (sender2, e2) => this.BeginCallback(_ => { bone = _.Objects.FirstOrDefault(o => o.Name.StartsWith("bone")); CreateAnchor(_, f.AnchorMargin, f.SnapAnchorToParent, f.CreateSymmetricalAnchor); }); f.FormClosing += (sender2, e2) => { e2.Cancel = true; f.Hide(); }; f.VisibleChanged += (sender2, e2) => { if (!f.Visible) { this.WindowClose(); } }; }; this.Exit += (sender, e) => f.Dispose(); this.Activate += (sender, e) => { if (e.Value) { EnsureBoneObject(e.Document); if (bone == null) { bone = new Metasequoia.Object { Name = "bone", Color = new Color(1, 0.8f, 0.5f), ColorValid = true, }; this.BeginCallback(_ => _.AddObject(bone)); } f.OnMaterialChanged(e.Document); f.OnObjectChanged(e.Document); f.Show(NativeWindow.FromHandle(Plugin.MainWindowHandle)); } else { createBonePointInfo = null; f.Hide(); } Plugin.RefreshView(); e.Handled = e.Value; }; this.IsActivated += (sender, e) => e.Handled = f.Visible; this.MaterialList += (sender, e) => { if (f.Visible) { f.OnMaterialChanged(e.Document); this.BeginCallback(_ => this.RedrawAllScene()); } }; this.ObjectList += (sender, e) => { if (f.Visible) { f.OnObjectChanged(e.Document); } }; this.Undo += (sender, e) => { if (createBonePointInfo != null) { createBonePointInfo = null; e.Handled = true; } }; this.RightButtonDown += (sender, e) => { if (createBonePointInfo != null) { createBonePointInfo = null; this.RedrawAllScene(); } }; this.LeftButtonDown += (sender, e) => { if (f.Visible) { switch (f.Mode) { case SkeletonMode.Bone: { var scr = new Point(e.X, e.Y, e.Scene.Convert3dToScreen(createBonePointInfo == null ? Point.Zero : createBonePointInfo.BeginWorld).Z); var hit = this.HitTest(e.Scene, new[] { e.X, e.Y }, HitType.Vertex); var pos = hit.HitType == HitType.Vertex ? hit.HitPos : this.GetSnappedPos(e.Scene, e.Scene.ConvertScreenTo3d(ref scr), this.GetEditOption().SnapGrid); if (createBonePointInfo == null) { createBonePointInfo = new CreateBonePointInfo { BeginWorld = pos, BeginVertexIndex = hit.HitType == HitType.Vertex && hit.ObjectIndex == bone.Index ? hit.VertexIndex : -1, } } ; else { createBonePointInfo.EndWorld = pos; createBonePointInfo.EndScreen = scr; createBonePointInfo.HasEnd = true; SetBoneSize(e.Scene, createBonePointInfo, new Point(e.X, e.Y, scr.Z), f.CreateRelativeBone); } this.RedrawAllScene(); e.Handled = true; } break; case SkeletonMode.Anchor: anchorSelect = new[] { Tuple.Create(e.X, e.Y), Tuple.Create(e.X, e.Y), }; e.Handled = true; break; } } }; this.LeftButtonMove += (sender, e) => { if (f.Visible) { switch (f.Mode) { case SkeletonMode.Bone: if (f.CreateNormalBone && createBonePointInfo != null && createBonePointInfo.HasEnd) { SetBoneSize(e.Scene, createBonePointInfo, new Point(e.X, e.Y, 0), f.CreateRelativeBone); this.RedrawAllScene(); e.Handled = true; } break; case SkeletonMode.Anchor: if (anchorSelect != null) { anchorSelect[1] = Tuple.Create(e.X, e.Y); this.RedrawScene(e.Scene); e.Handled = true; } break; } } }; this.LeftButtonUp += (sender, e) => { if (f.Visible) { switch (f.Mode) { case SkeletonMode.Bone: if (createBonePointInfo != null && createBonePointInfo.HasEnd) { this.BeginCallback(document => { if (createBonePointInfo.HasSize || f.CreateRelativeBone) { EnsureBoneObject(document); if (bone != null) { createBonePointInfo = new CreateBonePointInfo { BeginVertexIndex = CreateBone ( document, bone, createBonePointInfo, f.CreateNewMaterial, f.BoneName ), BeginWorld = createBonePointInfo.EndWorld, }; f.OnBoneCreated(); this.UpdateUndo(); } else { createBonePointInfo = null; } } else { createBonePointInfo.HasEnd = false; } this.RedrawAllScene(); e.Handled = true; }); } break; case SkeletonMode.Anchor: if (anchorSelect != null) { var isDrag = Math.Abs(anchorSelect[1].Item1 - anchorSelect[0].Item1) > 4 || Math.Abs(anchorSelect[1].Item2 - anchorSelect[0].Item2) > 4; var isAdd = Control.ModifierKeys.HasFlag(Keys.Shift); var isRemove = Control.ModifierKeys.HasFlag(Keys.Control); if (!isAdd & !isRemove) { e.Document.ClearSelect(Doc.ClearselectAll); } if (isDrag) { var objIdx = e.Document.CurrentObjectIndex; var obj = e.Document.Objects[objIdx]; var beginX = Math.Min(anchorSelect[0].Item1, anchorSelect[1].Item1); var beginY = Math.Min(anchorSelect[0].Item2, anchorSelect[1].Item2); var endX = Math.Max(anchorSelect[0].Item1, anchorSelect[1].Item1); var endY = Math.Max(anchorSelect[0].Item2, anchorSelect[1].Item2); foreach (var i in obj.Vertices) { var scr = e.Scene.Convert3dToScreen(i.Point); if (scr.X >= beginX && scr.X <= endX && scr.Y >= beginY && scr.Y <= endY) { i.IsSelected = !isRemove; } } } else { var test = this.HitTest(e.Scene, new[] { anchorSelect[0].Item1, anchorSelect[0].Item2 }, HitType.Vertex | HitType.Face); if (test.HitType != HitType.None && test.ObjectIndex == e.Document.CurrentObjectIndex) { switch (test.HitType) { case HitType.Vertex: if (isRemove) { e.Document.DeleteSelectVertex(test.ObjectIndex, test.VertexIndex); } else { e.Document.AddSelectVertex(test.ObjectIndex, test.VertexIndex); } break; case HitType.Face: foreach (var i in e.Document.Objects[test.ObjectIndex].Faces[test.FaceIndex].Points) { if (isRemove) { e.Document.DeleteSelectVertex(test.ObjectIndex, i); } else { e.Document.AddSelectVertex(test.ObjectIndex, i); } } break; } } } anchorSelect = null; this.RedrawAllScene(); e.Handled = true; } break; } } }; this.Draw += (sender, e) => { if (!f.Visible) { return; } switch (f.Mode) { case SkeletonMode.Bone: EnsureBoneObject(e.Document); if (bone != null) { using (var c = this.CreateDrawingObject(e.Document, DrawObjectVisibility.Point | DrawObjectVisibility.Line)) { c.Color = highlightColor; c.ColorValid = true; foreach (var i in bone.Faces) { c.AddFace(i.Points.Select(_ => bone.Vertices[_].Point) .Select(c.AddVertex)); } } } if (createBonePointInfo != null) { using (var c = this.CreateDrawingObject(e.Document, DrawObjectVisibility.Point | DrawObjectVisibility.Line)) { var vertices = new Point?[] { createBonePointInfo.BeginWorld, createBonePointInfo.HasEnd ? createBonePointInfo.EndWorld : (Point?)null, createBonePointInfo.HasSize ? createBonePointInfo.SizeWorld : (Point?)null, }.Where(_ => _.HasValue).Select(_ => c.AddVertex(_.Value)); c.Color = workingColor; c.ColorValid = true; c.AddFace(createBonePointInfo.Flip ? vertices.Reverse() : vertices); } } break; case SkeletonMode.Anchor: EnsureBoneObject(e.Document); if (bone != null) { using (var c = this.CreateDrawingObject(e.Document, DrawObjectVisibility.Point | DrawObjectVisibility.Line)) { c.Color = highlightColor; c.ColorValid = true; foreach (var i in bone.Faces.Where(_ => _.Material == e.Document.CurrentMaterialIndex && _.PointCount == 3)) { c.AddFace(i.Points.Select(_ => bone.Vertices[_].Point) .Select(c.AddVertex)); } } } if (anchorSelect != null) { using (var c = this.CreateDrawingObject(e.Document, DrawObjectVisibility.Line)) { var begin = anchorSelect[0]; var end = anchorSelect[1]; var z = e.Scene.Convert3dToScreen(Point.Zero).Z; var vertices = new[] { new Point(begin.Item1, begin.Item2, z), new Point(end.Item1, begin.Item2, z), new Point(end.Item1, end.Item2, z), new Point(begin.Item1, end.Item2, z), } .Select(_ => e.Scene.ConvertScreenTo3d(ref _)) .Select(_ => c.AddVertex(_)) .ToArray(); c.Color = workingColor; c.ColorValid = true; c.AddFace(new[] { vertices[0], vertices[1], }); c.AddFace(new[] { vertices[1], vertices[2], }); c.AddFace(new[] { vertices[2], vertices[3], }); c.AddFace(new[] { vertices[3], vertices[0], }); } } break; } }; }
public MainPlugin() { SkeletonForm f = null; CreateBonePointInfo createBonePointInfo = null; Tuple<int, int>[] anchorSelect = null; this.Initialize += (sender, e) => { f = new SkeletonForm(); f.ModeChanged += (sender2, e2) => { createBonePointInfo = null; Plugin.RefreshView(); }; f.CreateAnchor += (sender2, e2) => this.BeginCallback(_ => { bone = _.Objects.FirstOrDefault(o => o.Name.StartsWith("bone")); CreateAnchor(_, f.AnchorMargin, f.SnapAnchorToParent, f.CreateSymmetricalAnchor); }); f.FormClosing += (sender2, e2) => { e2.Cancel = true; f.Hide(); }; f.VisibleChanged += (sender2, e2) => { if (!f.Visible) this.WindowClose(); }; }; this.Exit += (sender, e) => f.Dispose(); this.Activate += (sender, e) => { if (e.Value) { EnsureBoneObject(e.Document); if (bone == null) { bone = new Metasequoia.Object { Name = "bone", Color = new Color(1, 0.8f, 0.5f), ColorValid = true, }; this.BeginCallback(_ => _.AddObject(bone)); } f.OnMaterialChanged(e.Document); f.OnObjectChanged(e.Document); f.Show(NativeWindow.FromHandle(Plugin.MainWindowHandle)); } else { createBonePointInfo = null; f.Hide(); } Plugin.RefreshView(); e.Handled = e.Value; }; this.IsActivated += (sender, e) => e.Handled = f.Visible; this.MaterialList += (sender, e) => { if (f.Visible) { f.OnMaterialChanged(e.Document); this.BeginCallback(_ => this.RedrawAllScene()); } }; this.ObjectList += (sender, e) => { if (f.Visible) f.OnObjectChanged(e.Document); }; this.Undo += (sender, e) => { if (createBonePointInfo != null) { createBonePointInfo = null; e.Handled = true; } }; this.RightButtonDown += (sender, e) => { if (createBonePointInfo != null) { createBonePointInfo = null; this.RedrawAllScene(); } }; this.LeftButtonDown += (sender, e) => { if (f.Visible) { switch (f.Mode) { case SkeletonMode.Bone: { var scr = new Point(e.X, e.Y, e.Scene.Convert3dToScreen(createBonePointInfo == null ? Point.Zero : createBonePointInfo.BeginWorld).Z); var hit = this.HitTest(e.Scene, new[] { e.X, e.Y }, HitType.Vertex); var pos = hit.HitType == HitType.Vertex ? hit.HitPos : this.GetSnappedPos(e.Scene, e.Scene.ConvertScreenTo3d(ref scr), this.GetEditOption().SnapGrid); if (createBonePointInfo == null) createBonePointInfo = new CreateBonePointInfo { BeginWorld = pos, BeginVertexIndex = hit.HitType == HitType.Vertex && hit.ObjectIndex == bone.Index ? hit.VertexIndex : -1, }; else { createBonePointInfo.EndWorld = pos; createBonePointInfo.EndScreen = scr; createBonePointInfo.HasEnd = true; SetBoneSize(e.Scene, createBonePointInfo, new Point(e.X, e.Y, scr.Z), f.CreateRelativeBone); } this.RedrawAllScene(); e.Handled = true; } break; case SkeletonMode.Anchor: anchorSelect = new[] { Tuple.Create(e.X, e.Y), Tuple.Create(e.X, e.Y), }; e.Handled = true; break; } } }; this.LeftButtonMove += (sender, e) => { if (f.Visible) switch (f.Mode) { case SkeletonMode.Bone: if (f.CreateNormalBone && createBonePointInfo != null && createBonePointInfo.HasEnd) { SetBoneSize(e.Scene, createBonePointInfo, new Point(e.X, e.Y, 0), f.CreateRelativeBone); this.RedrawAllScene(); e.Handled = true; } break; case SkeletonMode.Anchor: if (anchorSelect != null) { anchorSelect[1] = Tuple.Create(e.X, e.Y); this.RedrawScene(e.Scene); e.Handled = true; } break; } }; this.LeftButtonUp += (sender, e) => { if (f.Visible) switch (f.Mode) { case SkeletonMode.Bone: if (createBonePointInfo != null && createBonePointInfo.HasEnd) this.BeginCallback(document => { if (createBonePointInfo.HasSize || f.CreateRelativeBone) { EnsureBoneObject(document); if (bone != null) { createBonePointInfo = new CreateBonePointInfo { BeginVertexIndex = CreateBone ( document, bone, createBonePointInfo, f.CreateNewMaterial, f.BoneName ), BeginWorld = createBonePointInfo.EndWorld, }; f.OnBoneCreated(); this.UpdateUndo(); } else createBonePointInfo = null; } else createBonePointInfo.HasEnd = false; this.RedrawAllScene(); e.Handled = true; }); break; case SkeletonMode.Anchor: if (anchorSelect != null) { var isDrag = Math.Abs(anchorSelect[1].Item1 - anchorSelect[0].Item1) > 4 || Math.Abs(anchorSelect[1].Item2 - anchorSelect[0].Item2) > 4; var isAdd = Control.ModifierKeys.HasFlag(Keys.Shift); var isRemove = Control.ModifierKeys.HasFlag(Keys.Control); if (!isAdd & !isRemove) e.Document.ClearSelect(Doc.ClearselectAll); if (isDrag) { var objIdx = e.Document.CurrentObjectIndex; var obj = e.Document.Objects[objIdx]; var beginX = Math.Min(anchorSelect[0].Item1, anchorSelect[1].Item1); var beginY = Math.Min(anchorSelect[0].Item2, anchorSelect[1].Item2); var endX = Math.Max(anchorSelect[0].Item1, anchorSelect[1].Item1); var endY = Math.Max(anchorSelect[0].Item2, anchorSelect[1].Item2); foreach (var i in obj.Vertices) { var scr = e.Scene.Convert3dToScreen(i.Point); if (scr.X >= beginX && scr.X <= endX && scr.Y >= beginY && scr.Y <= endY) i.IsSelected = !isRemove; } } else { var test = this.HitTest(e.Scene, new[] { anchorSelect[0].Item1, anchorSelect[0].Item2 }, HitType.Vertex | HitType.Face); if (test.HitType != HitType.None && test.ObjectIndex == e.Document.CurrentObjectIndex) switch (test.HitType) { case HitType.Vertex: if (isRemove) e.Document.DeleteSelectVertex(test.ObjectIndex, test.VertexIndex); else e.Document.AddSelectVertex(test.ObjectIndex, test.VertexIndex); break; case HitType.Face: foreach (var i in e.Document.Objects[test.ObjectIndex].Faces[test.FaceIndex].Points) if (isRemove) e.Document.DeleteSelectVertex(test.ObjectIndex, i); else e.Document.AddSelectVertex(test.ObjectIndex, i); break; } } anchorSelect = null; this.RedrawAllScene(); e.Handled = true; } break; } }; this.Draw += (sender, e) => { if (!f.Visible) return; switch (f.Mode) { case SkeletonMode.Bone: EnsureBoneObject(e.Document); if (bone != null) using (var c = this.CreateDrawingObject(e.Document, DrawObjectVisibility.Point | DrawObjectVisibility.Line)) { c.Color = highlightColor; c.ColorValid = true; foreach (var i in bone.Faces) c.AddFace(i.Points.Select(_ => bone.Vertices[_].Point) .Select(c.AddVertex)); } if (createBonePointInfo != null) using (var c = this.CreateDrawingObject(e.Document, DrawObjectVisibility.Point | DrawObjectVisibility.Line)) { var vertices = new Point?[] { createBonePointInfo.BeginWorld, createBonePointInfo.HasEnd ? createBonePointInfo.EndWorld : (Point?)null, createBonePointInfo.HasSize ? createBonePointInfo.SizeWorld : (Point?)null, }.Where(_ => _.HasValue).Select(_ => c.AddVertex(_.Value)); c.Color = workingColor; c.ColorValid = true; c.AddFace(createBonePointInfo.Flip ? vertices.Reverse() : vertices); } break; case SkeletonMode.Anchor: EnsureBoneObject(e.Document); if (bone != null) using (var c = this.CreateDrawingObject(e.Document, DrawObjectVisibility.Point | DrawObjectVisibility.Line)) { c.Color = highlightColor; c.ColorValid = true; foreach (var i in bone.Faces.Where(_ => _.Material == e.Document.CurrentMaterialIndex && _.PointCount == 3)) c.AddFace(i.Points.Select(_ => bone.Vertices[_].Point) .Select(c.AddVertex)); } if (anchorSelect != null) using (var c = this.CreateDrawingObject(e.Document, DrawObjectVisibility.Line)) { var begin = anchorSelect[0]; var end = anchorSelect[1]; var z = e.Scene.Convert3dToScreen(Point.Zero).Z; var vertices = new[] { new Point(begin.Item1, begin.Item2, z), new Point(end.Item1, begin.Item2, z), new Point(end.Item1, end.Item2, z), new Point(begin.Item1, end.Item2, z), } .Select(_ => e.Scene.ConvertScreenTo3d(ref _)) .Select(_ => c.AddVertex(_)) .ToArray(); c.Color = workingColor; c.ColorValid = true; c.AddFace(new[] { vertices[0], vertices[1], }); c.AddFace(new[] { vertices[1], vertices[2], }); c.AddFace(new[] { vertices[2], vertices[3], }); c.AddFace(new[] { vertices[3], vertices[0], }); } break; } }; }