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
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
if((front != null) && map.AutoRemove) front.Dispose(); else AttachFrontP(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)]
public void DeleteItem()
public void DeleteItem() {
deleteItem(true); //mxd
}
private void deleteItem(bool createUndo)
{
// Make list of selected vertices
ICollection<Vertex> selected = General.Map.Map.GetSelectedVertices(true);
@ -740,27 +744,49 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(selected.Count > 0)
{
// Make undo
if(selected.Count > 1)
{
General.Map.UndoRedo.CreateUndo("Delete " + selected.Count + " vertices");
General.Interface.DisplayStatus(StatusType.Action, "Deleted " + selected.Count + " vertices.");
}
else
{
General.Map.UndoRedo.CreateUndo("Delete vertex");
General.Interface.DisplayStatus(StatusType.Action, "Deleted a vertex.");
if(createUndo) { //mxd
if(selected.Count > 1) {
General.Map.UndoRedo.CreateUndo("Delete " + selected.Count + " vertices");
General.Interface.DisplayStatus(StatusType.Action, "Deleted " + selected.Count + " vertices.");
} else {
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>();
List<Sector> possiblyInvalidSectors = new List<Sector>();
List<Sector> affectedSectors = new List<Sector>();
//mxd
foreach(Vertex v in selected) {
foreach(Linedef l in v.Linedefs) {
if(l.Front != null && 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.Front != null && l.Front.Sector != null){
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))
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));
foreach(Sidedef side in l.Front.Sector.Sidedefs) {
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 v2 = (ld2.Start == v) ? ld2.End : ld2.Start;
//mxd
DrawnVertex dv1 = new DrawnVertex();
DrawnVertex dv2 = new DrawnVertex();
dv1.stitchline = true;
dv2.stitchline = true;
//mxd. Check if removing a vertex will collapse a sector with 3 "outer" sides
bool skip = false;
if(ld1.Start == v) {
ld1.SetStartVertex(v2);
dv1.pos = v2.Position;
dv2.pos = v1.Position;
} else {
ld1.SetEndVertex(v2);
dv1.pos = v1.Position;
dv2.pos = v2.Position;
if(ld1.Front != null) {
foreach(Sidedef side in ld1.Front.Sector.Sidedefs) {
if(!possiblyInvalidSectors.Contains(ld1.Front.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
possiblyInvalidSectors.Add(ld1.Front.Sector);
skip = true;
}
}
}
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
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
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
General.Map.IsChanged = true;
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
MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, (int)mousepos.x, (int)mousepos.y, 0);
OnMouseMove(e);

View file

@ -17,6 +17,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
private float cageradius2;
private Vector3D boxp1;
private Vector3D boxp2;
private int storedHeight = int.MinValue;
// Undo/redo
private int undoticket;
@ -46,8 +47,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(vertex.Fields.ContainsKey(key)) {
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);
storedHeight = height;
}
} else if(storedHeight != int.MinValue) {
z = storedHeight;
vertex.Fields.Add(key, new UniValue(UniversalType.Float, z));
storedHeight = int.MinValue;
} else {
z = height;
}
@ -83,13 +90,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(ceilingVertex) {
height = sectors[0].CeilHeight;
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;
}
} else {
height = sectors[0].FloorHeight;
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;
}
}

View file

@ -51,7 +51,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
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);
index++;