From e4a924eb14ccde24816befff6977dc99f0cbd173 Mon Sep 17 00:00:00 2001 From: MaxED Date: Fri, 29 Nov 2013 14:45:29 +0000 Subject: [PATCH] Sectors and Linedefs modes: rectangular selection now checks for intersections between linedefs and itself when "select touching" is enabled. --- Source/Core/Geometry/Line2D.cs | 5 + Source/Core/Map/Linedef.cs | 3 - .../BuilderModes/ClassicModes/LinedefsMode.cs | 71 ++++--- .../BuilderModes/ClassicModes/SectorsMode.cs | 181 ++++++------------ 4 files changed, 95 insertions(+), 165 deletions(-) diff --git a/Source/Core/Geometry/Line2D.cs b/Source/Core/Geometry/Line2D.cs index cc787775..b0bb6f55 100644 --- a/Source/Core/Geometry/Line2D.cs +++ b/Source/Core/Geometry/Line2D.cs @@ -90,6 +90,11 @@ namespace CodeImp.DoomBuilder.Geometry return new Vector2D(dx, dy).GetNormal(); } + //mxd. This tests if given lines intersects + public static bool GetIntersection(Line2D line1, Line2D line2) { + return GetIntersection(line1.v1, line1.v2, line2.v1.x, line2.v1.y, line2.v2.x, line2.v2.y); + } + // This tests if the line intersects with the given line coordinates public static bool GetIntersection(Vector2D v1, Vector2D v2, float x3, float y3, float x4, float y4) { diff --git a/Source/Core/Map/Linedef.cs b/Source/Core/Map/Linedef.cs index 87d018ea..a62251b4 100644 --- a/Source/Core/Map/Linedef.cs +++ b/Source/Core/Map/Linedef.cs @@ -22,9 +22,6 @@ using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Geometry; using System.Drawing; using CodeImp.DoomBuilder.IO; -using CodeImp.DoomBuilder.Types; -using CodeImp.DoomBuilder.Data; -using CodeImp.DoomBuilder.GZBuilder.Tools; #endregion diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs index 71388725..568baa0d 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs @@ -239,6 +239,24 @@ namespace CodeImp.DoomBuilder.BuilderModes General.Interface.RefreshInfo(); General.Map.IsChanged = true; } + + //mxd + private bool isInSelectionRect(Linedef l, List selectionOutline) { + if(BuilderPlug.Me.MarqueSelectTouching) { + bool selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y); + + //check intersections with outline + if(!selected) { + foreach(Line2D line in selectionOutline) { + if(Line2D.GetIntersection(l.Line, line)) + return true; + } + } + return selected; + } + + return selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y); + } #endregion @@ -623,51 +641,30 @@ namespace CodeImp.DoomBuilder.BuilderModes if(selectionvolume) { + List selectionOutline = new List() { + new Line2D(selectionrect.Left, selectionrect.Top, selectionrect.Right, selectionrect.Top), + new Line2D(selectionrect.Right, selectionrect.Top, selectionrect.Right, selectionrect.Bottom), + new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Right, selectionrect.Bottom), + new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Left, selectionrect.Top) + }; + //mxd if(marqueSelectionMode == MarqueSelectionMode.SELECT) { // Go for all lines - if(BuilderPlug.Me.MarqueSelectTouching) { - foreach(Linedef l in General.Map.Map.Linedefs) - l.Selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y); - } else { - foreach(Linedef l in General.Map.Map.Linedefs) - l.Selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y); - } + foreach(Linedef l in General.Map.Map.Linedefs) + l.Selected = isInSelectionRect(l, selectionOutline); } else if(marqueSelectionMode == MarqueSelectionMode.ADD) { // Go for all lines - if(BuilderPlug.Me.MarqueSelectTouching) { - foreach(Linedef l in General.Map.Map.Linedefs) - l.Selected |= selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y); - } else { - foreach(Linedef l in General.Map.Map.Linedefs) - l.Selected |= selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y); - } + foreach(Linedef l in General.Map.Map.Linedefs) + l.Selected |= isInSelectionRect(l, selectionOutline); } else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) { // Go for all lines - if(BuilderPlug.Me.MarqueSelectTouching) { - foreach(Linedef l in General.Map.Map.Linedefs) { - if(selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y)) - l.Selected = false; - } - } else { - foreach(Linedef l in General.Map.Map.Linedefs) { - if(selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y)) - l.Selected = false; - } - } + foreach (Linedef l in General.Map.Map.Linedefs) + if(isInSelectionRect(l, selectionOutline)) l.Selected = false; } else { //should be Intersect - // Go for all lines - if(BuilderPlug.Me.MarqueSelectTouching) { - foreach(Linedef l in General.Map.Map.Linedefs) { - if(!selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && !selectionrect.Contains(l.End.Position.x, l.End.Position.y)) - l.Selected = false; - } - } else { - foreach(Linedef l in General.Map.Map.Linedefs) { - if(!selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || !selectionrect.Contains(l.End.Position.x, l.End.Position.y)) - l.Selected = false; - } - } + // Go for the eyes, Boo! Go for the eyes! + foreach(Linedef l in General.Map.Map.Linedefs) + if(!isInSelectionRect(l, selectionOutline)) l.Selected = false; } //mxd diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs index 2b8c334c..74aa3255 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs @@ -468,6 +468,39 @@ namespace CodeImp.DoomBuilder.BuilderModes } } + //mxd + private bool isInSelectionRect(Sector s, List selectionOutline) { + bool selected = false; + + if(BuilderPlug.Me.MarqueSelectTouching) { + //check endpoints + foreach (Sidedef side in s.Sidedefs) { + selected = (selectionrect.Contains(side.Line.Start.Position.x, side.Line.Start.Position.y) + || selectionrect.Contains(side.Line.End.Position.x, side.Line.End.Position.y)); + if (selected) return true; + } + + //check line intersections + foreach (Sidedef side in s.Sidedefs) { + foreach (Line2D line in selectionOutline) { + if(Line2D.GetIntersection(side.Line.Line, line)) + return true; + } + } + + return false; + } + + //check endpoints + foreach(Sidedef side in s.Sidedefs) { + selected = (selectionrect.Contains(side.Line.Start.Position.x, side.Line.Start.Position.y) + && selectionrect.Contains(side.Line.End.Position.x, side.Line.End.Position.y)); + if(!selected) return false; + } + + return selected; + } + #endregion #region ================== Events @@ -943,140 +976,38 @@ namespace CodeImp.DoomBuilder.BuilderModes if(selectionvolume) { + List selectionOutline = new List() { + new Line2D(selectionrect.Left, selectionrect.Top, selectionrect.Right, selectionrect.Top), + new Line2D(selectionrect.Right, selectionrect.Top, selectionrect.Right, selectionrect.Bottom), + new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Right, selectionrect.Bottom), + new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Left, selectionrect.Top) + }; + //mxd. collect changed sectors if(marqueSelectionMode == MarqueSelectionMode.SELECT){ - if(BuilderPlug.Me.MarqueSelectTouching) { - //select sectors fully and partially inside selection, deselect all other sectors - foreach(Sector s in General.Map.Map.Sectors) { - bool select = false; + bool select; + foreach (Sector s in General.Map.Map.Sectors) { + select = isInSelectionRect(s, selectionOutline); - foreach(Sidedef sd in s.Sidedefs) { - if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) { - select = true; - break; - } - } - - if(select && !s.Selected) - SelectSector(s, true, false); - else if(!select && s.Selected) - SelectSector(s, false, false); - } - }else{ - //select sectors fully inside selection, deselect all other sectors - foreach(Sector s in General.Map.Map.Sectors) { - bool select = true; - - foreach(Sidedef sd in s.Sidedefs) { - if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) { - select = false; - break; - } - } - - if(select && !s.Selected) - SelectSector(s, true, false); - else if(!select && s.Selected) - SelectSector(s, false, false); - } + if(select && !s.Selected) SelectSector(s, true, false); + else if(!select && s.Selected) SelectSector(s, false, false); } }else if(marqueSelectionMode == MarqueSelectionMode.ADD) { //additive selection - if(BuilderPlug.Me.MarqueSelectTouching) { - //select sectors fully and partially inside selection, leave others untouched - foreach(Sector s in General.Map.Map.Sectors) { - if(s.Selected) continue; - bool select = false; - - foreach(Sidedef sd in s.Sidedefs) { - if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) { - select = true; - break; - } - } - - if(select) SelectSector(s, true, false); - } - }else{ - //select sectors fully inside selection, leave others untouched - foreach(Sector s in General.Map.Map.Sectors) { - if(s.Selected) continue; - bool select = true; - - foreach(Sidedef sd in s.Sidedefs) { - if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) { - select = false; - break; - } - } - - if(select) SelectSector(s, true, false); - } + foreach(Sector s in General.Map.Map.Sectors) { + if(!s.Selected && isInSelectionRect(s, selectionOutline)) + SelectSector(s, true, false); } - } else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) { - if(BuilderPlug.Me.MarqueSelectTouching) { - //deselect sectors fully and partially inside selection, leave others untouched - foreach(Sector s in General.Map.Map.Sectors) { - if(!s.Selected) continue; - bool deselect = false; - - foreach(Sidedef sd in s.Sidedefs) { - if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) { - deselect = true; - break; - } - } - - if(deselect) SelectSector(s, false, false); - } - } else { - //deselect sectors fully inside selection, leave others untouched - foreach(Sector s in General.Map.Map.Sectors) { - if(!s.Selected) continue; - bool deselect = true; - - foreach(Sidedef sd in s.Sidedefs) { - if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) { - deselect = false; - break; - } - } - - if(deselect) SelectSector(s, false, false); - } + foreach(Sector s in General.Map.Map.Sectors) { + if(!s.Selected) continue; + if(isInSelectionRect(s, selectionOutline)) + SelectSector(s, false, false); } - } else { //should be Intersect - if(BuilderPlug.Me.MarqueSelectTouching) { - //deselect sectors which are fully outside selection - foreach(Sector s in General.Map.Map.Sectors) { - if(!s.Selected) continue; - bool keep = false; - - foreach(Sidedef sd in s.Sidedefs) { - if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) { - keep = true; - break; - } - } - - if(!keep) SelectSector(s, false, false); - } - } else { - //deselect sectors which are fully and partially outside selection - foreach(Sector s in General.Map.Map.Sectors) { - if(!s.Selected) continue; - bool keep = true; - - foreach(Sidedef sd in s.Sidedefs) { - if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) { - keep = false; - break; - } - } - - if(!keep) SelectSector(s, false, false); - } + foreach(Sector s in General.Map.Map.Sectors) { + if(!s.Selected) continue; + if(!isInSelectionRect(s, selectionOutline)) + SelectSector(s, false, false); } }