Added: more magic to the autoalign/select neighbours logic; These functions should not anymore wrap around to the opposite side of two-sided linedefs, allowing you to select back and front sides separately using shift+click, and reducing infinite broken autoalign loops.

This commit is contained in:
ZZYZX 2017-01-26 15:33:07 +02:00
parent dd48b5edfd
commit f4947a20be
6 changed files with 74 additions and 23 deletions

View file

@ -1863,6 +1863,12 @@ namespace CodeImp.DoomBuilder.Geometry
{
Sidedef side1 = forward ? ld.Front : ld.Back;
Sidedef side2 = forward ? ld.Back : ld.Front;
// [ZZ] don't iterate the same linedef twice.
//
if ((side1 != null && side1.Marked) ||
(side2 != null && side2.Marked)) continue;
if((ld.Start == v) && (side1 != null) && !side1.Marked)
{
if(SidedefTextureMatch(side1, texturelongnames))

View file

@ -30,6 +30,6 @@ using CodeImp.DoomBuilder;
// Build Number
// Revision
//
[assembly: AssemblyVersion("2.3.0.2845")]
[assembly: AssemblyVersion("2.3.0.2846")]
[assembly: NeutralResourcesLanguageAttribute("en")]
[assembly: AssemblyHash("7de5d10")]
[assembly: AssemblyHash("dd48b5e")]

View file

@ -763,7 +763,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
Sidedef side1 = (forward ? ld.Front : ld.Back);
Sidedef side2 = (forward ? ld.Back : ld.Front);
if((ld.Start == v) && (side1 != null) && !side1.Marked)
// [ZZ] don't iterate the same linedef twice.
//
if ((side1 != null && side1.Marked) ||
(side2 != null && side2.Marked)) continue;
if ((ld.Start == v) && (side1 != null) && !side1.Marked)
{
if(SidedefTextureMatch(mode, side1, texturelongnames))
stack.Push(new Tools.SidedefFillJob { forward = forward, sidedef = side1 });

View file

@ -29,5 +29,5 @@ using System.Resources;
// Build Number
// Revision
//
[assembly: AssemblyVersion("2.3.0.2845")]
[assembly: AssemblyVersion("2.3.0.2846")]
[assembly: NeutralResourcesLanguageAttribute("en")]

View file

@ -528,6 +528,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd
public void SelectNeighbours(bool select, bool matchtexture, bool matchheight)
{
SelectNeighbours(select, matchtexture, matchheight, true, true);
}
private void SelectNeighbours(bool select, bool matchtexture, bool matchheight, bool clearlinedefs, bool forward)
{
if(Sidedef.Sector == null || Triangles < 1 || (!matchtexture && !matchheight)) return;
@ -545,48 +550,77 @@ namespace CodeImp.DoomBuilder.BuilderModes
mode.RemoveSelectedObject(this);
}
// [ZZ] use the marking system.
if (clearlinedefs) General.Map.Map.ClearMarkedLinedefs(false);
Sidedef.Line.Marked = true;
// Select
SelectNeighbourLines(Sidedef.Line.Start.Linedefs, rect, select, matchtexture, matchheight);
SelectNeighbourLines(Sidedef.Line.End.Linedefs, rect, select, matchtexture, matchheight);
Vertex v;
if (forward)
{
v = Sidedef.IsFront ? Sidedef.Line.End : Sidedef.Line.Start;
SelectNeighbourLines(v.Linedefs, v, rect, select, matchtexture, matchheight, true);
v = Sidedef.IsFront ? Sidedef.Line.Start : Sidedef.Line.End;
SelectNeighbourLines(v.Linedefs, v, rect, select, matchtexture, matchheight, false);
}
else
{
v = Sidedef.IsFront ? Sidedef.Line.Start : Sidedef.Line.End;
SelectNeighbourLines(v.Linedefs, v, rect, select, matchtexture, matchheight, false);
v = Sidedef.IsFront ? Sidedef.Line.End : Sidedef.Line.Start;
SelectNeighbourLines(v.Linedefs, v, rect, select, matchtexture, matchheight, true);
}
}
//mxd
private void SelectNeighbourLines(IEnumerable<Linedef> lines, Rectangle sourcerect, bool select, bool matchtexture, bool matchheight)
private void SelectNeighbourLines(IEnumerable<Linedef> lines, Vertex v, Rectangle sourcerect, bool select, bool matchtexture, bool matchheight, bool forward)
{
foreach(Linedef line in lines)
{
if(line.Index == Sidedef.Line.Index) continue;
// [ZZ] decide which side of the next linedef to iterate.
// do NOT do both
Sidedef next = null;
Sidedef side1 = forward ? line.Front : line.Back;
Sidedef side2 = forward ? line.Back : line.Front;
if(line.Front != null && line.Front.Sector != null)
SelectNeighbourSideParts(line.Front, sourcerect, select, matchtexture, matchheight);
if (line.Start == v)
next = side1;
else if (line.End == v)
next = side2;
if(line.Back != null && line.Back.Sector != null)
SelectNeighbourSideParts(line.Back, sourcerect, select, matchtexture, matchheight);
if (next == null || next.Sector == null)
continue;
SelectNeighbourSideParts(next, sourcerect, select, matchtexture, matchheight, forward);
}
}
//mxd
private void SelectNeighbourSideParts(Sidedef side, Rectangle sourcerect, bool select, bool matchtexture, bool matchheight)
private void SelectNeighbourSideParts(Sidedef side, Rectangle sourcerect, bool select, bool matchtexture, bool matchheight, bool forward)
{
if (side.Line.Marked)
return;
BaseVisualSector s = (BaseVisualSector)mode.GetVisualSector(side.Sector);
if(s != null)
{
VisualSidedefParts parts = s.GetSidedefParts(side);
SelectNeighbourSidePart(parts.lower, sourcerect, select, matchtexture, matchheight);
SelectNeighbourSidePart(parts.middlesingle, sourcerect, select, matchtexture, matchheight);
SelectNeighbourSidePart(parts.middledouble, sourcerect, select, matchtexture, matchheight);
SelectNeighbourSidePart(parts.upper, sourcerect, select, matchtexture, matchheight);
SelectNeighbourSidePart(parts.lower, sourcerect, select, matchtexture, matchheight, forward);
SelectNeighbourSidePart(parts.middlesingle, sourcerect, select, matchtexture, matchheight, forward);
SelectNeighbourSidePart(parts.middledouble, sourcerect, select, matchtexture, matchheight, forward);
SelectNeighbourSidePart(parts.upper, sourcerect, select, matchtexture, matchheight, forward);
if(parts.middle3d != null)
{
foreach(VisualMiddle3D middle3D in parts.middle3d)
SelectNeighbourSidePart(middle3D, sourcerect, select, matchtexture, matchheight);
SelectNeighbourSidePart(middle3D, sourcerect, select, matchtexture, matchheight, forward);
}
}
}
//mxd
private void SelectNeighbourSidePart(BaseVisualGeometrySidedef visualside, Rectangle sourcerect, bool select, bool matchtexture, bool matchheight)
private void SelectNeighbourSidePart(BaseVisualGeometrySidedef visualside, Rectangle sourcerect, bool select, bool matchtexture, bool matchheight, bool forward)
{
if(visualside != null && visualside.Triangles > 0 && visualside.Selected != select)
{
@ -595,7 +629,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if((!matchtexture || (visualside.Texture == Texture && r.IntersectsWith(sourcerect))) &&
(!matchheight || (sourcerect.Height == r.Height && sourcerect.Y == r.Y)))
{
visualside.SelectNeighbours(select, matchtexture, matchheight);
visualside.SelectNeighbours(select, matchtexture, matchheight, false, forward);
}
}
}

View file

@ -4225,6 +4225,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
Sidedef side1 = forward ? ld.Front : ld.Back;
Sidedef side2 = forward ? ld.Back : ld.Front;
// [ZZ] I don't know what logic here is.
// I'm going to check if any side is marked, and if so, don't add.
if ((side1 != null && side1.Marked) ||
(side2 != null && side2.Marked)) continue;
if((ld.Start == v) && (side1 != null) && !side1.Marked)
{
List<Sidedef> controlSides = GetControlSides(side1, udmf); //mxd