More fixes in Vertex and Linedef deleting process and also Visual Vertex handles.

This commit is contained in:
MaxED 2013-03-25 14:49:03 +00:00
parent 4abcca3cf8
commit 6462ff5edb
4 changed files with 167 additions and 34 deletions

View file

@ -148,6 +148,14 @@ namespace CodeImp.DoomBuilder.Map
// Already set isdisposed so that changes can be prohibited // Already set isdisposed so that changes can be prohibited
isdisposed = true; isdisposed = true;
//mxd. If there are sectors on both sides, join them
if(front != null && front.Sector != null && back != null && back.Sector != null && front.Sector.Index != back.Sector.Index) {
if(front.Sector.BBox.Width * front.Sector.BBox.Height > back.Sector.BBox.Width * back.Sector.BBox.Height)
back.Sector.Join(front.Sector);
else
front.Sector.Join(back.Sector);
}
// Dispose sidedefs // Dispose sidedefs
if((front != null) && map.AutoRemove) front.Dispose(); else AttachFrontP(null); if((front != null) && map.AutoRemove) front.Dispose(); else AttachFrontP(null);
if((back != null) && map.AutoRemove) back.Dispose(); else AttachBackP(null); if((back != null) && map.AutoRemove) back.Dispose(); else AttachBackP(null);

View file

@ -730,7 +730,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
[BeginAction("deleteitem", BaseAction = true)] [BeginAction("deleteitem", BaseAction = true)]
public void DeleteItem() public void DeleteItem() {
deleteItem(true); //mxd
}
private void deleteItem(bool createUndo)
{ {
// Make list of selected vertices // Make list of selected vertices
ICollection<Vertex> selected = General.Map.Map.GetSelectedVertices(true); ICollection<Vertex> selected = General.Map.Map.GetSelectedVertices(true);
@ -740,27 +744,49 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(selected.Count > 0) if(selected.Count > 0)
{ {
// Make undo // Make undo
if(selected.Count > 1) if(createUndo) { //mxd
{ if(selected.Count > 1) {
General.Map.UndoRedo.CreateUndo("Delete " + selected.Count + " vertices"); General.Map.UndoRedo.CreateUndo("Delete " + selected.Count + " vertices");
General.Interface.DisplayStatus(StatusType.Action, "Deleted " + selected.Count + " vertices."); General.Interface.DisplayStatus(StatusType.Action, "Deleted " + selected.Count + " vertices.");
} } else {
else General.Map.UndoRedo.CreateUndo("Delete vertex");
{ General.Interface.DisplayStatus(StatusType.Action, "Deleted a vertex.");
General.Map.UndoRedo.CreateUndo("Delete vertex"); }
General.Interface.DisplayStatus(StatusType.Action, "Deleted a vertex.");
} }
//mxd. Find sectors, which will become invalid after vertex removal. //mxd. Find sectors, affected by vertex removal.
Dictionary<Sector, Vector2D> toMerge = new Dictionary<Sector, Vector2D>(); Dictionary<Sector, Vector2D> toMerge = new Dictionary<Sector, Vector2D>();
List<Sector> possiblyInvalidSectors = new List<Sector>();
List<Sector> affectedSectors = new List<Sector>();
//mxd
foreach(Vertex v in selected) { foreach(Vertex v in selected) {
foreach(Linedef l in v.Linedefs) { foreach(Linedef l in v.Linedefs) {
if(l.Front != null && l.Front.Sector.Sidedefs.Count < 4 && !toMerge.ContainsKey(l.Front.Sector)) if(l.Front != null && l.Front.Sector != null){
toMerge.Add(l.Front.Sector, new Vector2D(l.Front.Sector.BBox.Location.X + l.Front.Sector.BBox.Width/2, l.Front.Sector.BBox.Location.Y + l.Front.Sector.BBox.Height/2)); if(!affectedSectors.Contains(l.Front.Sector))
affectedSectors.Add(l.Front.Sector);
if(l.Back != null && l.Back.Sector.Sidedefs.Count < 4 && !toMerge.ContainsKey(l.Back.Sector)) foreach(Sidedef side in l.Front.Sector.Sidedefs) {
toMerge.Add(l.Back.Sector, new Vector2D(l.Back.Sector.BBox.Location.X + l.Back.Sector.BBox.Width / 2, l.Back.Sector.BBox.Location.Y + l.Back.Sector.BBox.Height / 2)); if(side.Other != null && side.Other.Sector != null && !affectedSectors.Contains(side.Other.Sector))
affectedSectors.Add(side.Other.Sector);
}
if(l.Front.Sector.Sidedefs.Count < 4 && !toMerge.ContainsKey(l.Front.Sector))
toMerge.Add(l.Front.Sector, new Vector2D(l.Front.Sector.BBox.Location.X + l.Front.Sector.BBox.Width/2, l.Front.Sector.BBox.Location.Y + l.Front.Sector.BBox.Height/2));
}
if(l.Back != null && l.Back.Sector != null) {
if(!affectedSectors.Contains(l.Back.Sector))
affectedSectors.Add(l.Back.Sector);
foreach(Sidedef side in l.Back.Sector.Sidedefs) {
if(side.Other != null && side.Other.Sector != null && !affectedSectors.Contains(side.Other.Sector))
affectedSectors.Add(side.Other.Sector);
}
if(l.Back.Sector.Sidedefs.Count < 4 && !toMerge.ContainsKey(l.Back.Sector))
toMerge.Add(l.Back.Sector, new Vector2D(l.Back.Sector.BBox.Location.X + l.Back.Sector.BBox.Width / 2, l.Back.Sector.BBox.Location.Y + l.Back.Sector.BBox.Height / 2));
}
} }
} }
@ -783,26 +809,85 @@ namespace CodeImp.DoomBuilder.BuilderModes
Vertex v1 = (ld1.Start == v) ? ld1.End : ld1.Start; Vertex v1 = (ld1.Start == v) ? ld1.End : ld1.Start;
Vertex v2 = (ld2.Start == v) ? ld2.End : ld2.Start; Vertex v2 = (ld2.Start == v) ? ld2.End : ld2.Start;
//mxd //mxd. Check if removing a vertex will collapse a sector with 3 "outer" sides
DrawnVertex dv1 = new DrawnVertex(); bool skip = false;
DrawnVertex dv2 = new DrawnVertex();
dv1.stitchline = true;
dv2.stitchline = true;
if(ld1.Start == v) { if(ld1.Front != null) {
ld1.SetStartVertex(v2); foreach(Sidedef side in ld1.Front.Sector.Sidedefs) {
dv1.pos = v2.Position; if(!possiblyInvalidSectors.Contains(ld1.Front.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
dv2.pos = v1.Position; possiblyInvalidSectors.Add(ld1.Front.Sector);
} else { skip = true;
ld1.SetEndVertex(v2); }
dv1.pos = v1.Position; }
dv2.pos = v2.Position;
} }
ld2.Dispose(); if(ld2.Front != null) {
foreach(Sidedef side in ld2.Front.Sector.Sidedefs) {
if(!possiblyInvalidSectors.Contains(ld2.Front.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
possiblyInvalidSectors.Add(ld2.Front.Sector);
skip = true;
}
}
}
if(ld1.Back != null) {
foreach(Sidedef side in ld1.Back.Sector.Sidedefs) {
if(!possiblyInvalidSectors.Contains(ld1.Back.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
possiblyInvalidSectors.Add(ld1.Back.Sector);
skip = true;
}
}
}
if(ld2.Back != null) {
foreach(Sidedef side in ld2.Back.Sector.Sidedefs) {
if(!possiblyInvalidSectors.Contains(ld2.Back.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
possiblyInvalidSectors.Add(ld2.Back.Sector);
skip = true;
}
}
}
//mxd //mxd
Tools.DrawLines(new List<DrawnVertex>() { dv1, dv2 }); if(!skip) {
DrawnVertex dv1 = new DrawnVertex();
DrawnVertex dv2 = new DrawnVertex();
dv1.stitchline = true;
dv2.stitchline = true;
dv1.stitch = true;
dv2.stitch = true;
if(ld1.Start == v) {
dv1.pos = v2.Position;
dv2.pos = v1.Position;
} else {
dv1.pos = v1.Position;
dv2.pos = v2.Position;
}
Tools.DrawLines(new List<DrawnVertex>() { dv1, dv2 });
General.Map.IsChanged = true;
General.Map.Map.Update();
//if both of the lines are single sided, remove newly created sector
if((ld1.Front == null || ld1.Back == null) && (ld2.Front == null || ld2.Back == null)) {
List<Linedef> newLines = General.Map.Map.GetMarkedLinedefs(true);
int index = ld1.Front != null ? ld1.Front.Sector.Index : ld1.Back.Sector.Index;
General.Map.Map.GetSectorByIndex(index).Dispose();
foreach(Linedef l in newLines) {
if(l.Front != null && l.Front.Sector != null && !affectedSectors.Contains(l.Front.Sector))
affectedSectors.Add(l.Front.Sector);
if(l.Back != null && l.Back.Sector != null && !affectedSectors.Contains(l.Back.Sector))
affectedSectors.Add(l.Back.Sector);
}
} else {
ld1.Dispose();
ld2.Dispose();
}
}
} }
} }
@ -814,10 +899,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd //mxd
Tools.MergeInvalidSectors(toMerge); Tools.MergeInvalidSectors(toMerge);
foreach(Sector s in possiblyInvalidSectors) {
//still invalid?
if(!s.IsDisposed && s.Sidedefs.Count < 3) s.Dispose();
}
foreach(Sector s in affectedSectors) {
if(s.IsDisposed) continue;
foreach(Sidedef side in s.Sidedefs){
if((side.Line.Front == null && side.Line.Back != null) || (side.Line.Front != null && side.Line.Back == null)){
side.Line.ApplySidedFlags();
}else if(side.Line.Front == null && side.Line.Back != null && side.Line.Back.Sector != null) {
// Flip linedef
side.Line.FlipVertices();
side.Line.FlipSidedefs();
side.Line.ApplySidedFlags();
}
}
}
// Update cache values // Update cache values
General.Map.IsChanged = true; General.Map.IsChanged = true;
General.Map.Map.Update(); General.Map.Map.Update();
//mxd. Because... well... some new vertices might have been created during vertex removal process...
if(General.Map.Map.GetSelectedVertices(true).Count > 0) {
deleteItem(false);
return;
}
// Invoke a new mousemove so that the highlighted item updates // Invoke a new mousemove so that the highlighted item updates
MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, (int)mousepos.x, (int)mousepos.y, 0); MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, (int)mousepos.x, (int)mousepos.y, 0);
OnMouseMove(e); OnMouseMove(e);

View file

@ -17,6 +17,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
private float cageradius2; private float cageradius2;
private Vector3D boxp1; private Vector3D boxp1;
private Vector3D boxp2; private Vector3D boxp2;
private int storedHeight = int.MinValue;
// Undo/redo // Undo/redo
private int undoticket; private int undoticket;
@ -46,8 +47,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(vertex.Fields.ContainsKey(key)) { if(vertex.Fields.ContainsKey(key)) {
z = vertex.Fields.GetValue(key, 0f); z = vertex.Fields.GetValue(key, 0f);
if(z == height) //don't create garbage data! if(z == height) { //don't create garbage data!
vertex.Fields.Remove(key); vertex.Fields.Remove(key);
storedHeight = height;
}
} else if(storedHeight != int.MinValue) {
z = storedHeight;
vertex.Fields.Add(key, new UniValue(UniversalType.Float, z));
storedHeight = int.MinValue;
} else { } else {
z = height; z = height;
} }
@ -83,13 +90,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(ceilingVertex) { if(ceilingVertex) {
height = sectors[0].CeilHeight; height = sectors[0].CeilHeight;
for(int i = 1; i < sectors.Length; i++) { for(int i = 1; i < sectors.Length; i++) {
if(sectors[i].CeilHeight < height) if(sectors[i].Sidedefs.Count == 3 && sectors[i].CeilHeight < height)
height = sectors[i].CeilHeight; height = sectors[i].CeilHeight;
} }
} else { } else {
height = sectors[0].FloorHeight; height = sectors[0].FloorHeight;
for(int i = 1; i < sectors.Length; i++) { for(int i = 1; i < sectors.Length; i++) {
if(sectors[i].FloorHeight > height) if(sectors[i].Sidedefs.Count == 3 && sectors[i].FloorHeight > height)
height = sectors[i].FloorHeight; height = sectors[i].FloorHeight;
} }
} }

View file

@ -51,7 +51,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
VertexData vd = data.Mode.GetVertexData(v); VertexData vd = data.Mode.GetVertexData(v);
vd.AddUpdateSector(data.Sector, true);
foreach(Linedef line in v.Linedefs) {
if(line.Front != null && line.Front.Sector != null)
vd.AddUpdateSector(line.Front.Sector, false);
if(line.Back != null && line.Back.Sector != null)
vd.AddUpdateSector(line.Back.Sector, false);
}
data.Mode.UpdateVertexHandle(v); data.Mode.UpdateVertexHandle(v);
index++; index++;