mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 13:51:40 +00:00
the "Marked" property of map elements now indicates the set we are working with, not the user selection
This commit is contained in:
parent
018f8ab26a
commit
e95a24f281
12 changed files with 270 additions and 157 deletions
|
@ -58,16 +58,16 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
private List<Vector2D> oldpositions;
|
||||
|
||||
// List of selected items
|
||||
private ICollection<Vertex> selectedverts;
|
||||
protected ICollection<Vertex> selectedverts;
|
||||
|
||||
// List of non-selected items
|
||||
private ICollection<Vertex> unselectedverts;
|
||||
protected ICollection<Vertex> unselectedverts;
|
||||
|
||||
// List of unstable lines
|
||||
protected ICollection<Linedef> unstablelines;
|
||||
|
||||
// List of unselected lines
|
||||
protected ICollection<Linedef> unselectedlines;
|
||||
protected ICollection<Linedef> snaptolines;
|
||||
|
||||
// Keep track of view changes
|
||||
private float lastoffsetx;
|
||||
|
@ -107,22 +107,27 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
#region ================== Methods
|
||||
|
||||
// Constructor to start dragging immediately
|
||||
protected void StartDrag(EditMode basemode, Vertex dragitem, Vector2D dragstartmappos, ICollection<Vertex> selected, ICollection<Vertex> unselected)
|
||||
protected void StartDrag(EditMode basemode, Vector2D dragstartmappos)
|
||||
{
|
||||
// Initialize
|
||||
this.dragitem = dragitem;
|
||||
this.dragstartmappos = dragstartmappos;
|
||||
this.basemode = basemode;
|
||||
|
||||
Cursor.Current = Cursors.AppStarting;
|
||||
|
||||
// Make list of selected vertices
|
||||
selectedverts = selected;
|
||||
selectedverts = General.Map.Map.GetMarkedVertices(true);
|
||||
|
||||
// Make list of non-selected vertices
|
||||
// This will be used for snapping to nearest items
|
||||
unselectedverts = unselected;
|
||||
unselectedverts = General.Map.Map.GetMarkedVertices(false);
|
||||
|
||||
// Get the nearest vertex for snapping
|
||||
dragitem = MapSet.NearestVertex(selectedverts, dragstartmappos);
|
||||
|
||||
// Lines to snap to
|
||||
snaptolines = General.Map.Map.LinedefsFromMarkedVertices(true, false, false);
|
||||
|
||||
// Make old positions list
|
||||
// We will use this as reference to move the vertices, or to move them back on cancel
|
||||
oldpositions = new List<Vector2D>(selectedverts.Count);
|
||||
|
@ -148,13 +153,14 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
private bool MoveGeometryRelative(Vector2D offset, bool snapgrid, bool snapnearest)
|
||||
{
|
||||
Vector2D oldpos = dragitem.Position;
|
||||
Vector2D anchorpos = dragitemposition + offset;
|
||||
int i = 0;
|
||||
|
||||
// Snap to nearest?
|
||||
if(snapnearest)
|
||||
{
|
||||
// Find nearest unselected vertex within range
|
||||
Vertex nv = MapSet.NearestVertexSquareRange(unselectedverts, mousemappos, VerticesMode.VERTEX_HIGHLIGHT_RANGE / renderer.Scale);
|
||||
Vertex nv = MapSet.NearestVertexSquareRange(unselectedverts, anchorpos, VerticesMode.VERTEX_HIGHLIGHT_RANGE / renderer.Scale);
|
||||
if(nv != null)
|
||||
{
|
||||
// Move the dragged item
|
||||
|
@ -169,7 +175,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
else
|
||||
{
|
||||
// Find the nearest unselected line within range
|
||||
Linedef nl = MapSet.NearestLinedefRange(unselectedlines, mousemappos, LinedefsMode.LINEDEF_HIGHLIGHT_RANGE / renderer.Scale);
|
||||
Linedef nl = MapSet.NearestLinedefRange(snaptolines, anchorpos, LinedefsMode.LINEDEF_HIGHLIGHT_RANGE / renderer.Scale);
|
||||
if(nl != null)
|
||||
{
|
||||
// Snap to grid?
|
||||
|
@ -183,7 +189,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
Vector2D found_coord = new Vector2D();
|
||||
foreach(Vector2D v in coords)
|
||||
{
|
||||
Vector2D delta = mousemappos - v;
|
||||
Vector2D delta = anchorpos - v;
|
||||
if(delta.GetLengthSq() < found_distance)
|
||||
{
|
||||
found_distance = delta.GetLengthSq();
|
||||
|
@ -203,10 +209,10 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
else
|
||||
{
|
||||
// Move the dragged item
|
||||
dragitem.Move(nl.NearestOnLine(mousemappos));
|
||||
dragitem.Move(nl.NearestOnLine(anchorpos));
|
||||
|
||||
// Align to line here
|
||||
offset = nl.NearestOnLine(mousemappos) - dragitemposition;
|
||||
offset = nl.NearestOnLine(anchorpos) - dragitemposition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,13 +222,13 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
if(snapgrid)
|
||||
{
|
||||
// Move the dragged item
|
||||
dragitem.Move(dragitemposition + offset);
|
||||
dragitem.Move(anchorpos);
|
||||
|
||||
// Snap item to grid
|
||||
dragitem.SnapToGrid();
|
||||
|
||||
// Adjust the offset
|
||||
offset += dragitem.Position - (dragitemposition + offset);
|
||||
offset += dragitem.Position - anchorpos;
|
||||
}
|
||||
|
||||
// Drag item moved?
|
||||
|
@ -293,7 +299,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
MoveGeometryRelative(mousemappos - dragstartmappos, snaptogrid, snaptonearest);
|
||||
|
||||
// Stitch geometry
|
||||
General.Map.Map.StitchGeometry(selectedverts, unselectedverts);
|
||||
if(snaptonearest) General.Map.Map.StitchGeometry();
|
||||
|
||||
// Update cached values
|
||||
General.Map.Map.Update();
|
||||
|
|
|
@ -63,17 +63,17 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Constructor to start dragging immediately
|
||||
public DragLinedefsMode(EditMode basemode, Vector2D dragstartmappos)
|
||||
{
|
||||
// Get the nearest vertex for snapping
|
||||
Vertex nearest = MapSet.NearestVertex(General.Map.Map.GetVerticesFromLinesSelection(true), dragstartmappos);
|
||||
// Mark what we are dragging
|
||||
General.Map.Map.ClearAllMarks();
|
||||
General.Map.Map.MarkSelectedLinedefs(true, true);
|
||||
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||
foreach(Vertex v in verts) v.Marked = true;
|
||||
|
||||
// Get selected lines
|
||||
selectedlines = General.Map.Map.GetLinedefsSelection(true);
|
||||
unselectedlines = General.Map.Map.GetLinedefsSelection(false);
|
||||
|
||||
|
||||
// Initialize
|
||||
base.StartDrag(basemode, nearest, dragstartmappos,
|
||||
General.Map.Map.GetVerticesFromLinesSelection(true),
|
||||
General.Map.Map.GetVerticesFromLinesSelectionEx(false));
|
||||
base.StartDrag(basemode, dragstartmappos);
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -107,7 +107,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
{
|
||||
// Select vertices from lines selection
|
||||
General.Map.Map.ClearSelectedVertices();
|
||||
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesSelection(true);
|
||||
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||
foreach(Vertex v in verts) v.Selected = true;
|
||||
|
||||
// Perform normal disengage
|
||||
|
@ -133,7 +133,8 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
if(renderer.StartPlotter(true))
|
||||
{
|
||||
// Render lines and vertices
|
||||
renderer.PlotLinedefSet(unselectedlines);
|
||||
renderer.PlotLinedefSet(snaptolines);
|
||||
renderer.PlotLinedefSet(unstablelines);
|
||||
renderer.PlotLinedefSet(selectedlines);
|
||||
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
||||
|
||||
|
|
|
@ -64,18 +64,18 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Constructor to start dragging immediately
|
||||
public DragSectorsMode(EditMode basemode, Vector2D dragstartmappos)
|
||||
{
|
||||
// Get the nearest vertex for snapping
|
||||
Vertex nearest = MapSet.NearestVertex(General.Map.Map.GetVerticesFromLinesSelection(true), dragstartmappos);
|
||||
// Mark what we are dragging
|
||||
General.Map.Map.ClearAllMarks();
|
||||
General.Map.Map.MarkSelectedLinedefs(true, true);
|
||||
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||
foreach(Vertex v in verts) v.Marked = true;
|
||||
|
||||
// Get selected lines
|
||||
selectedlines = General.Map.Map.GetLinedefsSelection(true);
|
||||
unselectedlines = General.Map.Map.GetLinedefsSelection(false);
|
||||
selectedsectors = General.Map.Map.GetSectorsSelection(true);
|
||||
|
||||
// Initialize
|
||||
base.StartDrag(basemode, nearest, dragstartmappos,
|
||||
General.Map.Map.GetVerticesFromLinesSelection(true),
|
||||
General.Map.Map.GetVerticesFromLinesSelectionEx(false));
|
||||
base.StartDrag(basemode, dragstartmappos);
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -109,7 +109,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
{
|
||||
// Select vertices from lines selection
|
||||
General.Map.Map.ClearSelectedVertices();
|
||||
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesSelection(true);
|
||||
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||
foreach(Vertex v in verts) v.Selected = true;
|
||||
|
||||
// Perform normal disengage
|
||||
|
@ -139,7 +139,8 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
if(renderer.StartPlotter(true))
|
||||
{
|
||||
// Render lines and vertices
|
||||
renderer.PlotLinedefSet(unselectedlines);
|
||||
renderer.PlotLinedefSet(snaptolines);
|
||||
renderer.PlotLinedefSet(unstablelines);
|
||||
renderer.PlotLinedefSet(selectedlines);
|
||||
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
||||
|
||||
|
|
|
@ -98,12 +98,16 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
|
||||
Cursor.Current = Cursors.AppStarting;
|
||||
|
||||
// Get the nearest thing for snapping
|
||||
dragitem = MapSet.NearestThing(General.Map.Map.GetThingsSelection(true), dragstartmappos);
|
||||
// Mark what we are dragging
|
||||
General.Map.Map.ClearAllMarks();
|
||||
General.Map.Map.MarkSelectedThings(true, true);
|
||||
|
||||
// Get selected things
|
||||
selectedthings = General.Map.Map.GetThingsSelection(true);
|
||||
unselectedthings = General.Map.Map.GetThingsSelection(false);
|
||||
selectedthings = General.Map.Map.GetMarkedThings(true);
|
||||
unselectedthings = General.Map.Map.GetMarkedThings(false);
|
||||
|
||||
// Get the nearest thing for snapping
|
||||
dragitem = MapSet.NearestThing(selectedthings, dragstartmappos);
|
||||
|
||||
// Make old positions list
|
||||
// We will use this as reference to move the vertices, or to move them back on cancel
|
||||
|
@ -284,7 +288,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
MoveThingsRelative(mousemappos - dragstartmappos, snaptogrid, snaptonearest);
|
||||
|
||||
// Update cached values
|
||||
General.Map.Map.Update();
|
||||
General.Map.Map.Update(false, false);
|
||||
|
||||
// Map is changed
|
||||
General.Map.IsChanged = true;
|
||||
|
|
|
@ -50,9 +50,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
|
||||
#region ================== Variables
|
||||
|
||||
private ICollection<Vertex> selectedverts;
|
||||
private ICollection<Vertex> unselectedverts;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
@ -64,15 +61,12 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Constructor to start dragging immediately
|
||||
public DragVerticesMode(EditMode basemode, Vertex dragitem, Vector2D dragstartmappos)
|
||||
{
|
||||
// Get selected vertices
|
||||
selectedverts = General.Map.Map.GetVerticesSelection(true);
|
||||
unselectedverts = General.Map.Map.GetVerticesSelection(false);
|
||||
unselectedlines = General.Map.Map.LinedefsFromSelectedVertices(true, false, false);
|
||||
|
||||
// Mark what we are dragging
|
||||
General.Map.Map.ClearAllMarks();
|
||||
General.Map.Map.MarkSelectedVertices(true, true);
|
||||
|
||||
// Initialize
|
||||
base.StartDrag(basemode, dragitem, dragstartmappos,
|
||||
General.Map.Map.GetVerticesSelection(true),
|
||||
General.Map.Map.GetVerticesSelection(false));
|
||||
base.StartDrag(basemode, dragstartmappos);
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
|
|
@ -161,8 +161,8 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
|
||||
// STEP 2: Merge the new geometry
|
||||
foreach(Vertex v in mergeverts) v.Selected = true;
|
||||
map.StitchGeometry(mergeverts, nonmergeverts);
|
||||
foreach(Vertex v in mergeverts) v.Marked = true;
|
||||
map.StitchGeometry();
|
||||
|
||||
// STEP 3: Make sectors where possible
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
// Selections
|
||||
private bool selected;
|
||||
private bool marked;
|
||||
|
||||
// Disposing
|
||||
private bool isdisposed = false;
|
||||
|
@ -95,6 +96,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
public int Action { get { return action; } set { action = value; } }
|
||||
public int Tag { get { return tag; } set { tag = value; if((tag < 0) || (tag > MapSet.HIGHEST_TAG)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } }
|
||||
public bool Selected { get { return selected; } set { selected = value; } }
|
||||
public bool Marked { get { return marked; } set { marked = value; } }
|
||||
public float LengthSq { get { return lengthsq; } }
|
||||
public float Length { get { return length; } }
|
||||
public float LengthInv { get { return lengthinv; } }
|
||||
|
@ -483,7 +485,8 @@ namespace CodeImp.DoomBuilder.Map
|
|||
CopyPropertiesTo(nl);
|
||||
SetEndVertex(v);
|
||||
nl.selected = this.selected;
|
||||
|
||||
nl.marked = this.marked;
|
||||
|
||||
// Copy front sidedef if exists
|
||||
if(front != null)
|
||||
{
|
||||
|
@ -628,7 +631,8 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
// If either of the two lines was selected, keep the other selected
|
||||
if(this.selected) other.selected = true;
|
||||
|
||||
if(this.marked) other.marked = true;
|
||||
|
||||
// Apply single/double sided flags
|
||||
other.ApplySidedFlags();
|
||||
|
||||
|
|
|
@ -411,73 +411,6 @@ namespace CodeImp.DoomBuilder.Map
|
|||
foreach(Sector s in sectors) s.Selected = false;
|
||||
}
|
||||
|
||||
// Returns a collection of vertices that match a selected state
|
||||
public ICollection<Vertex> GetVerticesSelection(bool selected)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices) if(v.Selected == selected) list.Add(v);
|
||||
return list;
|
||||
}
|
||||
|
||||
// Returns a collection of vertices that match a selected state on the linedefs
|
||||
public ICollection<Vertex> GetVerticesFromLinesSelection(bool selected)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices)
|
||||
{
|
||||
foreach(Linedef l in v.Linedefs)
|
||||
{
|
||||
if(l.Selected == selected)
|
||||
{
|
||||
list.Add(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// Returns a collection of vertices that match a selected state on the linedefs
|
||||
// The difference with GetVerticesFromLinesSelection is that in this method
|
||||
// ALL linedefs of a vertex must match the specified selected state.
|
||||
public ICollection<Vertex> GetVerticesFromLinesSelectionEx(bool selected)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices)
|
||||
{
|
||||
bool qualified = true;
|
||||
foreach(Linedef l in v.Linedefs)
|
||||
{
|
||||
if(l.Selected != selected)
|
||||
{
|
||||
qualified = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(qualified) list.Add(v);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// Returns a collection of vertices that match a selected state on the linedefs
|
||||
public ICollection<Vertex> GetVerticesFromSectorsSelection(bool selected)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices)
|
||||
{
|
||||
foreach(Linedef l in v.Linedefs)
|
||||
{
|
||||
if( ((l.Front != null) && (l.Front.Sector.Selected == selected)) ||
|
||||
((l.Back != null) && (l.Back.Sector.Selected == selected)) )
|
||||
{
|
||||
list.Add(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// Returns a collection of things that match a selected state
|
||||
public ICollection<Thing> GetThingsSelection(bool selected)
|
||||
{
|
||||
|
@ -504,6 +437,164 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== Marking
|
||||
|
||||
// This clears all marks
|
||||
public void ClearAllMarks()
|
||||
{
|
||||
ClearMarkedVertices(false);
|
||||
ClearMarkedThings(false);
|
||||
ClearMarkedLinedefs(false);
|
||||
ClearMarkedSectors(false);
|
||||
}
|
||||
|
||||
// This clears marked vertices
|
||||
public void ClearMarkedVertices(bool mark)
|
||||
{
|
||||
foreach(Vertex v in vertices) v.Marked = mark;
|
||||
}
|
||||
|
||||
// This clears marked things
|
||||
public void ClearMarkedThings(bool mark)
|
||||
{
|
||||
foreach(Thing t in things) t.Marked = mark;
|
||||
}
|
||||
|
||||
// This clears marked linedefs
|
||||
public void ClearMarkedLinedefs(bool mark)
|
||||
{
|
||||
foreach(Linedef l in linedefs) l.Marked = mark;
|
||||
}
|
||||
|
||||
// This clears marked sectors
|
||||
public void ClearMarkedSectors(bool mark)
|
||||
{
|
||||
foreach(Sector s in sectors) s.Marked = mark;
|
||||
}
|
||||
|
||||
// Returns a collection of vertices that match a marked state
|
||||
public ICollection<Vertex> GetMarkedVertices(bool mark)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices) if(v.Marked == mark) list.Add(v);
|
||||
return list;
|
||||
}
|
||||
|
||||
// Returns a collection of things that match a marked state
|
||||
public ICollection<Thing> GetMarkedThings(bool mark)
|
||||
{
|
||||
List<Thing> list = new List<Thing>(things.Count >> 1);
|
||||
foreach(Thing t in things) if(t.Marked == mark) list.Add(t);
|
||||
return list;
|
||||
}
|
||||
|
||||
// Returns a collection of linedefs that match a marked state
|
||||
public ICollection<Linedef> GetMarkedLinedefs(bool mark)
|
||||
{
|
||||
List<Linedef> list = new List<Linedef>(linedefs.Count >> 1);
|
||||
foreach(Linedef l in linedefs) if(l.Marked == mark) list.Add(l);
|
||||
return list;
|
||||
}
|
||||
|
||||
// Returns a collection of sectors that match a marked state
|
||||
public ICollection<Sector> GetMarkedSectors(bool mark)
|
||||
{
|
||||
List<Sector> list = new List<Sector>(sectors.Count >> 1);
|
||||
foreach(Sector s in sectors) if(s.Marked == mark) list.Add(s);
|
||||
return list;
|
||||
}
|
||||
|
||||
// This creates a marking from selection
|
||||
public void MarkSelectedVertices(bool selected, bool mark)
|
||||
{
|
||||
foreach(Vertex v in vertices) if(v.Selected == selected) v.Marked |= mark;
|
||||
}
|
||||
|
||||
// This creates a marking from selection
|
||||
public void MarkSelectedLinedefs(bool selected, bool mark)
|
||||
{
|
||||
foreach(Linedef l in linedefs) if(l.Selected == selected) l.Marked |= mark;
|
||||
}
|
||||
|
||||
// This creates a marking from selection
|
||||
public void MarkSelectedSectors(bool selected, bool mark)
|
||||
{
|
||||
foreach(Sector s in sectors) if(s.Selected == selected) s.Marked |= mark;
|
||||
}
|
||||
|
||||
// This creates a marking from selection
|
||||
public void MarkSelectedThings(bool selected, bool mark)
|
||||
{
|
||||
foreach(Thing t in things) if(t.Selected == selected) t.Marked |= mark;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of vertices that match a marked state on the linedefs
|
||||
/// </summary>
|
||||
public ICollection<Vertex> GetVerticesFromLinesMarks(bool mark)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices)
|
||||
{
|
||||
foreach(Linedef l in v.Linedefs)
|
||||
{
|
||||
if(l.Marked == mark)
|
||||
{
|
||||
list.Add(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of vertices that match a marked state on the linedefs
|
||||
/// The difference with GetVerticesFromLinesMarks is that in this method
|
||||
/// ALL linedefs of a vertex must match the specified marked state.
|
||||
/// </summary>
|
||||
public ICollection<Vertex> GetVerticesFromAllLinesMarks(bool mark)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices)
|
||||
{
|
||||
bool qualified = true;
|
||||
foreach(Linedef l in v.Linedefs)
|
||||
{
|
||||
if(l.Marked != mark)
|
||||
{
|
||||
qualified = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(qualified) list.Add(v);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of vertices that match a marked state on the linedefs
|
||||
/// </summary>
|
||||
public ICollection<Vertex> GetVerticesFromSectorsMarks(bool mark)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices)
|
||||
{
|
||||
foreach(Linedef l in v.Linedefs)
|
||||
{
|
||||
if(((l.Front != null) && (l.Front.Sector.Marked == mark)) ||
|
||||
((l.Back != null) && (l.Back.Sector.Marked == mark)))
|
||||
{
|
||||
list.Add(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Areas
|
||||
|
||||
// This creates an area from vertices
|
||||
|
@ -612,55 +703,60 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
#region ================== Stitching
|
||||
|
||||
// This stitches geometry
|
||||
public int StitchGeometry(ICollection<Vertex> movingverts, ICollection<Vertex> fixedverts)
|
||||
/// <summary>
|
||||
/// Stitches marked geometry with non-marked geometry. Returns the number of stitches made.
|
||||
/// </summary>
|
||||
public int StitchGeometry()
|
||||
{
|
||||
ICollection<Linedef> movinglines;
|
||||
ICollection<Linedef> fixedlines;
|
||||
ICollection<Vertex> nearbyfixedverts;
|
||||
ICollection<Vertex> movingverts;
|
||||
ICollection<Vertex> fixedverts;
|
||||
Rectangle editarea;
|
||||
int stitches = 0;
|
||||
int stitchundo;
|
||||
|
||||
// Find vertices
|
||||
movingverts = General.Map.Map.GetMarkedVertices(true);
|
||||
fixedverts = General.Map.Map.GetMarkedVertices(false);
|
||||
|
||||
if(General.MainWindow.AutoMerge)
|
||||
{
|
||||
// Make undo for the stitching
|
||||
stitchundo = General.Map.UndoRedo.CreateUndo("stitch geometry", UndoGroup.None, 0);
|
||||
// Make undo for the stitching
|
||||
stitchundo = General.Map.UndoRedo.CreateUndo("stitch geometry", UndoGroup.None, 0);
|
||||
|
||||
// Find lines that moved during the drag
|
||||
movinglines = LinedefsFromSelectedVertices(false, true, true);
|
||||
// Find lines that moved during the drag
|
||||
movinglines = LinedefsFromMarkedVertices(false, true, true);
|
||||
|
||||
// Find all non-moving lines
|
||||
fixedlines = LinedefsFromSelectedVertices(true, false, false);
|
||||
// Find all non-moving lines
|
||||
fixedlines = LinedefsFromMarkedVertices(true, false, false);
|
||||
|
||||
// Determine area in which we are editing
|
||||
editarea = MapSet.CreateArea(movinglines);
|
||||
editarea.Inflate((int)Math.Ceiling(General.Settings.StitchDistance),
|
||||
(int)Math.Ceiling(General.Settings.StitchDistance));
|
||||
// Determine area in which we are editing
|
||||
editarea = MapSet.CreateArea(movinglines);
|
||||
editarea.Inflate((int)Math.Ceiling(General.Settings.StitchDistance),
|
||||
(int)Math.Ceiling(General.Settings.StitchDistance));
|
||||
|
||||
// Join nearby vertices
|
||||
stitches += MapSet.JoinVertices(fixedverts, movingverts, true, General.Settings.StitchDistance);
|
||||
// Join nearby vertices
|
||||
stitches += MapSet.JoinVertices(fixedverts, movingverts, true, General.Settings.StitchDistance);
|
||||
|
||||
// Update cached values of lines because we need their length/angle
|
||||
Update(true, false);
|
||||
// Update cached values of lines because we need their length/angle
|
||||
Update(true, false);
|
||||
|
||||
// Split moving lines with unselected vertices
|
||||
nearbyfixedverts = MapSet.FilterByArea(fixedverts, ref editarea);
|
||||
stitches += MapSet.SplitLinesByVertices(movinglines, nearbyfixedverts, General.Settings.StitchDistance, movinglines);
|
||||
// Split moving lines with unselected vertices
|
||||
nearbyfixedverts = MapSet.FilterByArea(fixedverts, ref editarea);
|
||||
stitches += MapSet.SplitLinesByVertices(movinglines, nearbyfixedverts, General.Settings.StitchDistance, movinglines);
|
||||
|
||||
// Split non-moving lines with selected vertices
|
||||
fixedlines = MapSet.FilterByArea(fixedlines, ref editarea);
|
||||
stitches += MapSet.SplitLinesByVertices(fixedlines, movingverts, General.Settings.StitchDistance, movinglines);
|
||||
// Split non-moving lines with selected vertices
|
||||
fixedlines = MapSet.FilterByArea(fixedlines, ref editarea);
|
||||
stitches += MapSet.SplitLinesByVertices(fixedlines, movingverts, General.Settings.StitchDistance, movinglines);
|
||||
|
||||
// Remove looped linedefs
|
||||
stitches += MapSet.RemoveLoopedLinedefs(movinglines);
|
||||
// Remove looped linedefs
|
||||
stitches += MapSet.RemoveLoopedLinedefs(movinglines);
|
||||
|
||||
// Join overlapping lines
|
||||
stitches += MapSet.JoinOverlappingLines(movinglines);
|
||||
// Join overlapping lines
|
||||
stitches += MapSet.JoinOverlappingLines(movinglines);
|
||||
|
||||
// No stitching done? then withdraw undo
|
||||
if(stitches == 0) General.Map.UndoRedo.WithdrawUndo(stitchundo);
|
||||
}
|
||||
// No stitching done? then withdraw undo
|
||||
if(stitches == 0) General.Map.UndoRedo.WithdrawUndo(stitchundo);
|
||||
|
||||
return stitches;
|
||||
}
|
||||
|
@ -1105,9 +1201,9 @@ namespace CodeImp.DoomBuilder.Map
|
|||
return null;
|
||||
}
|
||||
|
||||
// This makes a list of lines related to vertex selection
|
||||
// A line is unstable when one vertex is selected and the other isn't.
|
||||
public ICollection<Linedef> LinedefsFromSelectedVertices(bool includeunselected, bool includestable, bool includeunstable)
|
||||
// This makes a list of lines related to marked vertices
|
||||
// A line is unstable when one vertex is marked and the other isn't.
|
||||
public ICollection<Linedef> LinedefsFromMarkedVertices(bool includeunselected, bool includestable, bool includeunstable)
|
||||
{
|
||||
List<Linedef> list = new List<Linedef>((linedefs.Count / 2) + 1);
|
||||
|
||||
|
@ -1115,9 +1211,9 @@ namespace CodeImp.DoomBuilder.Map
|
|||
foreach(Linedef l in linedefs)
|
||||
{
|
||||
// Check if this is to be included
|
||||
if((includestable && (l.Start.Selected && l.End.Selected)) ||
|
||||
(includeunstable && (l.Start.Selected ^ l.End.Selected)) ||
|
||||
(includeunselected && (!l.Start.Selected && !l.End.Selected)) )
|
||||
if((includestable && (l.Start.Marked && l.End.Marked)) ||
|
||||
(includeunstable && (l.Start.Marked ^ l.End.Marked)) ||
|
||||
(includeunselected && (!l.Start.Marked && !l.End.Marked)))
|
||||
{
|
||||
// Add to list
|
||||
list.Add(l);
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
// Selections
|
||||
private bool selected;
|
||||
private bool marked;
|
||||
|
||||
// Cloning
|
||||
private Sector clone;
|
||||
|
@ -96,6 +97,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
public int Tag { get { return tag; } set { tag = value; if((tag < 0) || (tag > MapSet.HIGHEST_TAG)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } }
|
||||
public int Brightness { get { return brightness; } set { brightness = value; } }
|
||||
public bool Selected { get { return selected; } set { selected = value; } }
|
||||
public bool Marked { get { return marked; } set { marked = value; } }
|
||||
public bool UpdateNeeded { get { return updateneeded; } set { updateneeded |= value; } }
|
||||
public Sector Clone { get { return clone; } set { clone = value; } }
|
||||
public TriangleList Triangles { get { return triangles; } set { triangles = value; } }
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
// Additional fields
|
||||
private SortedList<string, object> fields;
|
||||
|
||||
|
||||
// Disposing
|
||||
private bool isdisposed = false;
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
// Selections
|
||||
private bool selected;
|
||||
private bool marked;
|
||||
|
||||
// Additional fields
|
||||
private SortedList<string, object> fields;
|
||||
|
@ -89,6 +90,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
public int Action { get { return action; } }
|
||||
public byte[] Args { get { return args; } }
|
||||
public bool Selected { get { return selected; } set { selected = value; } }
|
||||
public bool Marked { get { return marked; } set { marked = value; } }
|
||||
public float Size { get { return size; } }
|
||||
public float IconOffset { get { return iconoffset; } }
|
||||
public PixelColor Color { get { return color; } }
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
// Selections
|
||||
private bool selected;
|
||||
private bool marked;
|
||||
|
||||
// Cloning
|
||||
private Vertex clone;
|
||||
|
@ -77,6 +78,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
public int Y { get { return y; } }
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
public bool Selected { get { return selected; } set { selected = value; } }
|
||||
public bool Marked { get { return marked; } set { marked = value; } }
|
||||
public Vertex Clone { get { return clone; } set { clone = value; } }
|
||||
public SortedList<string, object> Fields { get { return fields; } }
|
||||
|
||||
|
@ -248,6 +250,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
// If either of the two vertices was selected, keep the other selected
|
||||
if(this.selected) other.selected = true;
|
||||
if(this.marked) other.marked = true;
|
||||
|
||||
// Remove this vertex
|
||||
this.Dispose();
|
||||
|
|
Loading…
Reference in a new issue