Esempio n. 1
0
        static int CreateBone(Document doc, Metasequoia.Object obj, CreateBonePointInfo info, bool newMaterial, string boneName)
        {
            var vertices = new[]
            {
                info.BeginVertexIndex != -1
                                        ? info.BeginVertexIndex
                                        : obj.AddVertex(info.BeginWorld)
            }.Concat(new[]
            {
                info.EndWorld,
                info.HasSize ? info.SizeWorld : (Point?)null,
            }
                     .Where(_ => _.HasValue)
                     .Select(_ => obj.AddVertex(_.Value)))
            .ToArray();

            if (vertices.Length == 3 && info.Flip)
            {
                vertices = vertices.Reverse().ToArray();
            }

            var face = obj.AddFace(vertices);

            if (info.HasSize && newMaterial)
            {
                var r   = new Random();
                var mat = doc.Materials.Where(_ => _.Name == boneName)
                          .Select(_ => (int?)_.Index)
                          .FirstOrDefault()
                          ?? doc.AddMaterial(new Material
                {
                    Name  = boneName,
                    Alpha = (float)(0.5 + r.NextDouble() * 0.4),
                    Color = new Color((float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble()),
                });

                obj.SetFaceMaterial(face, mat);
                doc.CurrentMaterialIndex = mat;
            }
            else
            {
                obj.SetFaceMaterial(face, doc.CurrentMaterialIndex);
            }

            foreach (var i in vertices)
            {
                doc.AddSelectVertex(obj.Index, i);
            }

            for (int i = 0; i < (vertices.Length == 2 ? 1 : vertices.Length); i++)
            {
                doc.AddSelectLine(obj.Index, face, i);
            }

            doc.AddSelectFace(obj.Index, face);

            return(vertices[1]);
        }
		protected override bool Main(Document doc)
		{
			var owner = NativeWindow.FromHandle(Plugin.MainWindowHandle);
			var vertices = doc.Objects.SelectMany(_ => _.Vertices)
									  .Where(_ => _.IsSelected)
									  .ToArray();

			if (vertices.Length == 0)
			{
				MessageBox.Show(owner, "対象の頂点がありません。", "バウンディングボックスの作成", MessageBoxButtons.OK, MessageBoxIcon.Information);

				return false;
			}

			using (var f = new CreateBoundingBoxForm
			{
				CreateAtNewObject = createNewObject,
				CreateAtCurrentObject = !createNewObject,
				CreateMargin = margin,
			})
				if (f.ShowDialog(owner) == DialogResult.OK)
				{
					createNewObject = f.CreateAtNewObject;
					margin = f.CreateMargin;
				}
				else
					return false;

			var min = vertices.Aggregate(vertices.First().Point, (x, y) => new Point(Math.Min(x.X, y.Point.X), Math.Min(x.Y, y.Point.Y), Math.Min(x.Z, y.Point.Z))) - margin;
			var max = vertices.Aggregate(vertices.First().Point, (x, y) => new Point(Math.Max(x.X, y.Point.X), Math.Max(x.Y, y.Point.Y), Math.Max(x.Z, y.Point.Z))) + margin;
			var newVertices = new[]
			{
				new Point(min.X, max.Y, max.Z),
				new Point(min.X, min.Y, max.Z),
				new Point(max.X, max.Y, max.Z),
				new Point(max.X, min.Y, max.Z),
				new Point(max.X, max.Y, min.Z),
				new Point(max.X, min.Y, min.Z),
				new Point(min.X, max.Y, min.Z),
				new Point(min.X, min.Y, min.Z),
			};
			var newIndices = new[]
			{
				new[] { 0, 2, 3, 1 },
				new[] { 2, 4, 5, 3 },
				new[] { 4, 6, 7, 5 },
				new[] { 6, 0, 1, 7 },
				new[] { 6, 4, 2, 0 },
				new[] { 1, 3, 5, 7 },
			};
			var obj = doc.Objects[doc.CurrentObjectIndex];

			if (createNewObject || obj.Locking)
			{
				obj = new Metasequoia.Object();
				createNewObject = true;
			}

			var realVertices = newVertices.Select(obj.AddVertex).ToArray();
			var currentMaterial = doc.CurrentMaterialIndex;

			foreach (var i in newIndices)
				obj.Faces[obj.AddFace(i.Select(_ => realVertices[_]).ToArray())].Material = currentMaterial;

			if (createNewObject)
			{
				doc.AddObject(obj);
				obj.IsSelected = true;
			}

			return true;
		}
Esempio n. 3
0
 void EnsureBoneObject(Document doc)
 {
     bone = doc.Objects.FirstOrDefault(_ => _.Name.StartsWith("bone"));
 }
Esempio n. 4
0
        void CreateAnchor(Document doc, float margin, bool snap, bool autoMirror)
        {
            if (doc.CurrentObjectIndex == -1 ||
                doc.CurrentMaterialIndex == -1)
            {
                return;
            }

            var targetObject   = doc.Objects[doc.CurrentObjectIndex];
            var targetBoneFace = bone == null ? null : bone.Faces.FirstOrDefault(_ => _.Material == doc.CurrentMaterialIndex && _.PointCount == 3);
            var targetBone     = targetBoneFace == null ? null : new Bone(doc, targetBoneFace);
            var beginToEnd     = targetBone == null ? Point.Zero : targetBone.End.Point - targetBone.Begin.Point;
            var unit           = new Point(0, 1, 0);
            var axis           = Point.GetCrossProduct(unit, beginToEnd).Normalize();
            var angle          = Point.GetCrossingAngle(unit, beginToEnd);

            if (axis == Point.Zero)
            {
                axis = new Point(0, 1, 0);
            }

            var targetBoneMatrix = targetBone == null || !snap
                                ? Matrix.Identity
                                : Matrix.CreateFromAxisAngle(axis, angle) * Matrix.CreateTranslation(targetBone.Begin.Point);
            var targetBoneInverseMatrix = targetBone == null || !snap
                                ? Matrix.Identity
                                : Matrix.Invert(targetBoneMatrix);
            var anchorName = "anchor|" + targetObject.Name.Split(':').Last();

            while (doc.Objects.Any(_ => _.Name == anchorName))
            {
                anchorName = anchorName.Replace("|", "_|");
            }

            var vertices = targetObject.Vertices
                           .Where(_ => _.IsSelected)
                           .Select(_ => Point.Transform(_.Point, targetBoneInverseMatrix))
                           .ToArray();

            if (!vertices.Any())
            {
                return;
            }

            var min = vertices.Aggregate(vertices.First(), (x, y) => new Point(Math.Min(x.X, y.X), Math.Min(x.Y, y.Y), Math.Min(x.Z, y.Z))) - margin;
            var max = vertices.Aggregate(vertices.First(), (x, y) => new Point(Math.Max(x.X, y.X), Math.Max(x.Y, y.Y), Math.Max(x.Z, y.Z))) + margin;
            var obj = new Metasequoia.Object
            {
                Name = anchorName,
            };
            var newVertices = new[]
            {
                new Point(min.X, max.Y, max.Z),
                new Point(min.X, min.Y, max.Z),
                new Point(max.X, max.Y, max.Z),
                new Point(max.X, min.Y, max.Z),
                new Point(max.X, max.Y, min.Z),
                new Point(max.X, min.Y, min.Z),
                new Point(min.X, max.Y, min.Z),
                new Point(min.X, min.Y, min.Z),
            }.Select(_ => Point.Transform(_, targetBoneMatrix)).Select(obj.AddVertex).ToArray();

            foreach (var i in new[]
            {
                new[] { 0, 2, 3, 1 },
                new[] { 2, 4, 5, 3 },
                new[] { 4, 6, 7, 5 },
                new[] { 6, 0, 1, 7 },
                new[] { 6, 4, 2, 0 },
                new[] { 1, 3, 5, 7 },
            })
            {
                obj.Faces[obj.AddFace(i.Select(_ => newVertices[_]))].Material = doc.CurrentMaterialIndex;
            }

            if (autoMirror && doc.Materials[doc.CurrentMaterialIndex].Name.EndsWith("[]"))
            {
                obj.MirrorType = ObjectMirror.Normal;
                obj.MirrorAxis = ObjectMirrorAxis.X;
            }

            doc.AddObject(obj);
        }
Esempio n. 5
0
        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;
                }
            };
        }
Esempio n. 6
0
		void CreateAnchor(Document doc, float margin, bool snap, bool autoMirror)
		{
			if (doc.CurrentObjectIndex == -1 ||
				doc.CurrentMaterialIndex == -1)
				return;

			var targetObject = doc.Objects[doc.CurrentObjectIndex];
			var targetBoneFace = bone == null ? null : bone.Faces.FirstOrDefault(_ => _.Material == doc.CurrentMaterialIndex && _.PointCount == 3);
			var targetBone = targetBoneFace == null ? null : new Bone(doc, targetBoneFace);
			var beginToEnd = targetBone == null ? Point.Zero : targetBone.End.Point - targetBone.Begin.Point;
			var unit = new Point(0, 1, 0);
			var axis = Point.GetCrossProduct(unit, beginToEnd).Normalize();
			var angle = Point.GetCrossingAngle(unit, beginToEnd);

			if (axis == Point.Zero)
				axis = new Point(0, 1, 0);

			var targetBoneMatrix = targetBone == null || !snap
				? Matrix.Identity
				: Matrix.CreateFromAxisAngle(axis, angle) * Matrix.CreateTranslation(targetBone.Begin.Point);
			var targetBoneInverseMatrix = targetBone == null || !snap
				? Matrix.Identity
				: Matrix.Invert(targetBoneMatrix);
			var anchorName = "anchor|" + targetObject.Name.Split(':').Last();

			while (doc.Objects.Any(_ => _.Name == anchorName))
				anchorName = anchorName.Replace("|", "_|");

			var vertices = targetObject.Vertices
									   .Where(_ => _.IsSelected)
									   .Select(_ => Point.Transform(_.Point, targetBoneInverseMatrix))
									   .ToArray();

			if (!vertices.Any())
				return;

			var min = vertices.Aggregate(vertices.First(), (x, y) => new Point(Math.Min(x.X, y.X), Math.Min(x.Y, y.Y), Math.Min(x.Z, y.Z))) - margin;
			var max = vertices.Aggregate(vertices.First(), (x, y) => new Point(Math.Max(x.X, y.X), Math.Max(x.Y, y.Y), Math.Max(x.Z, y.Z))) + margin;
			var obj = new Metasequoia.Object
			{
				Name = anchorName,
			};
			var newVertices = new[]
			{
				new Point(min.X, max.Y, max.Z),
				new Point(min.X, min.Y, max.Z),
				new Point(max.X, max.Y, max.Z),
				new Point(max.X, min.Y, max.Z),
				new Point(max.X, max.Y, min.Z),
				new Point(max.X, min.Y, min.Z),
				new Point(min.X, max.Y, min.Z),
				new Point(min.X, min.Y, min.Z),
			}.Select(_ => Point.Transform(_, targetBoneMatrix)).Select(obj.AddVertex).ToArray();

			foreach (var i in new[]
			{
				new[] { 0, 2, 3, 1 },
				new[] { 2, 4, 5, 3 },
				new[] { 4, 6, 7, 5 },
				new[] { 6, 0, 1, 7 },
				new[] { 6, 4, 2, 0 },
				new[] { 1, 3, 5, 7 },
			})
				obj.Faces[obj.AddFace(i.Select(_ => newVertices[_]))].Material = doc.CurrentMaterialIndex;

			if (autoMirror && doc.Materials[doc.CurrentMaterialIndex].Name.EndsWith("[]"))
			{
				obj.MirrorType = ObjectMirror.Normal;
				obj.MirrorAxis = ObjectMirrorAxis.X;
			}

			doc.AddObject(obj);
		}
Esempio n. 7
0
		void EnsureBoneObject(Document doc)
		{
			bone = doc.Objects.FirstOrDefault(_ => _.Name.StartsWith("bone"));
		}
Esempio n. 8
0
		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;
				}
			};
		}
Esempio n. 9
0
        protected override bool Main(Document doc)
        {
            var owner    = NativeWindow.FromHandle(Plugin.MainWindowHandle);
            var vertices = doc.Objects.SelectMany(_ => _.Vertices)
                           .Where(_ => _.IsSelected)
                           .ToArray();

            if (vertices.Length == 0)
            {
                MessageBox.Show(owner, "対象の頂点がありません。", "バウンディングボックスの作成", MessageBoxButtons.OK, MessageBoxIcon.Information);

                return(false);
            }

            using (var f = new CreateBoundingBoxForm
            {
                CreateAtNewObject = createNewObject,
                CreateAtCurrentObject = !createNewObject,
                CreateMargin = margin,
            })
                if (f.ShowDialog(owner) == DialogResult.OK)
                {
                    createNewObject = f.CreateAtNewObject;
                    margin          = f.CreateMargin;
                }
                else
                {
                    return(false);
                }

            var min         = vertices.Aggregate(vertices.First().Point, (x, y) => new Point(Math.Min(x.X, y.Point.X), Math.Min(x.Y, y.Point.Y), Math.Min(x.Z, y.Point.Z))) - margin;
            var max         = vertices.Aggregate(vertices.First().Point, (x, y) => new Point(Math.Max(x.X, y.Point.X), Math.Max(x.Y, y.Point.Y), Math.Max(x.Z, y.Point.Z))) + margin;
            var newVertices = new[]
            {
                new Point(min.X, max.Y, max.Z),
                new Point(min.X, min.Y, max.Z),
                new Point(max.X, max.Y, max.Z),
                new Point(max.X, min.Y, max.Z),
                new Point(max.X, max.Y, min.Z),
                new Point(max.X, min.Y, min.Z),
                new Point(min.X, max.Y, min.Z),
                new Point(min.X, min.Y, min.Z),
            };
            var newIndices = new[]
            {
                new[] { 0, 2, 3, 1 },
                new[] { 2, 4, 5, 3 },
                new[] { 4, 6, 7, 5 },
                new[] { 6, 0, 1, 7 },
                new[] { 6, 4, 2, 0 },
                new[] { 1, 3, 5, 7 },
            };
            var obj = doc.Objects[doc.CurrentObjectIndex];

            if (createNewObject || obj.Locking)
            {
                obj             = new Metasequoia.Object();
                createNewObject = true;
            }

            var realVertices    = newVertices.Select(obj.AddVertex).ToArray();
            var currentMaterial = doc.CurrentMaterialIndex;

            foreach (var i in newIndices)
            {
                obj.Faces[obj.AddFace(i.Select(_ => realVertices[_]).ToArray())].Material = currentMaterial;
            }

            if (createNewObject)
            {
                doc.AddObject(obj);
                obj.IsSelected = true;
            }

            return(true);
        }