Fixed, Fit Textures action: sidedefs were not sorted properly when trying to use the action on several disconnected sidedef strips with the same texture.

Fixed, Fit Textures action: update was not triggered when toggling "Fit across connected surfaces" check-box.
This commit is contained in:
MaxED 2015-01-12 18:18:48 +00:00
parent e4cad3e06c
commit 64e198451d
3 changed files with 75 additions and 53 deletions

View file

@ -23,6 +23,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
internal readonly Dictionary<SortedVisualSide, bool> NextSides; internal readonly Dictionary<SortedVisualSide, bool> NextSides;
internal readonly Dictionary<SortedVisualSide, bool> PreviousSides; internal readonly Dictionary<SortedVisualSide, bool> PreviousSides;
internal readonly int Index; internal readonly int Index;
internal int GroupIndex = -1;
private static int index; private static int index;
//Initial texture coordinates //Initial texture coordinates
@ -198,49 +199,54 @@ namespace CodeImp.DoomBuilder.BuilderModes
foreach (KeyValuePair<long, List<BaseVisualGeometrySidedef>> pair in sidesbytexture) foreach (KeyValuePair<long, List<BaseVisualGeometrySidedef>> pair in sidesbytexture)
{ {
// Create strips // Create strips
IEnumerable<SortedVisualSide> group = ConnectSides(pair.Value); Dictionary<int, List<SortedVisualSide>> strips = ConnectSides(pair.Value);
// Calculate global bounds... // Calculate global bounds...
int minx = int.MaxValue; foreach(List<SortedVisualSide> group in strips.Values)
int maxx = int.MinValue;
int miny = int.MaxValue;
int maxy = int.MinValue;
foreach(SortedVisualSide side in group)
{ {
if(side.Bounds.X < minx) minx = side.Bounds.X; int minx = int.MaxValue;
if(side.Bounds.X + side.Bounds.Width > maxx) maxx = side.Bounds.X + side.Bounds.Width; int maxx = int.MinValue;
if(side.Bounds.Y < miny) miny = side.Bounds.Y; int miny = int.MaxValue;
if(side.Bounds.Y + side.Bounds.Height > maxy) maxy = side.Bounds.Y + side.Bounds.Height; int maxy = int.MinValue;
foreach(SortedVisualSide side in group)
{
if(side.Bounds.X < minx) minx = side.Bounds.X;
if(side.Bounds.X + side.Bounds.Width > maxx) maxx = side.Bounds.X + side.Bounds.Width;
if(side.Bounds.Y < miny) miny = side.Bounds.Y;
if(side.Bounds.Y + side.Bounds.Height > maxy) maxy = side.Bounds.Y + side.Bounds.Height;
}
Rectangle bounds = new Rectangle(minx, miny, maxx - minx, maxy - miny);
// Normalize Y-offset
int offsety = bounds.Y;
bounds.Y = 0;
// Apply changes
foreach(SortedVisualSide side in group)
{
side.Bounds.Y -= offsety;
side.GlobalBounds = bounds;
}
// Add to result
result.AddRange(group);
} }
Rectangle bounds = new Rectangle(minx, miny, maxx - minx, maxy - miny);
// Normalize Y-offset
int offsety = bounds.Y;
bounds.Y = 0;
// Apply changes
foreach(SortedVisualSide side in group)
{
side.Bounds.Y -= offsety;
side.GlobalBounds = bounds;
}
// Add to result
result.AddRange(group);
} }
return result; return result;
} }
// Connect sides, left to right // Connect sides, left to right and sort them into connected groups
// NextSides - sides connected to the right (Start) vertex, // NextSides - sides connected to the right (Start) vertex,
// PreviousSides - sides connected to the left (End) vertex // PreviousSides - sides connected to the left (End) vertex
private static IEnumerable<SortedVisualSide> ConnectSides(List<BaseVisualGeometrySidedef> allsides) private static Dictionary<int, List<SortedVisualSide>> ConnectSides(List<BaseVisualGeometrySidedef> allsides)
{ {
List<SortedVisualSide> result = new List<SortedVisualSide>(); Dictionary<int, List<SortedVisualSide>> result = new Dictionary<int, List<SortedVisualSide>>();
List<SortedVisualSide> sides = new List<SortedVisualSide>(allsides.Count); List<SortedVisualSide> sides = new List<SortedVisualSide>(allsides.Count);
int groupindex = 0;
foreach (BaseVisualGeometrySidedef side in allsides) foreach (BaseVisualGeometrySidedef side in allsides)
{ {
sides.Add(new SortedVisualSide(side)); sides.Add(new SortedVisualSide(side));
@ -248,6 +254,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
foreach(SortedVisualSide curside in sides) foreach(SortedVisualSide curside in sides)
{ {
if(curside.GroupIndex == -1) curside.GroupIndex = groupindex++;
// Find sides connected to the end of curside // Find sides connected to the end of curside
foreach(SortedVisualSide nextside in sides) foreach(SortedVisualSide nextside in sides)
{ {
@ -255,8 +263,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(nextside.Start == curside.End && nextside.End != curside.Start) if(nextside.Start == curside.End && nextside.End != curside.Start)
{ {
// Add both ways // Add both ways
if(!nextside.PreviousSides.ContainsKey(curside)) nextside.PreviousSides.Add(curside, false); if(!nextside.PreviousSides.ContainsKey(curside))
if(!curside.NextSides.ContainsKey(nextside)) curside.NextSides.Add(nextside, false); {
nextside.PreviousSides.Add(curside, false);
nextside.GroupIndex = curside.GroupIndex;
}
if(!curside.NextSides.ContainsKey(nextside))
{
curside.NextSides.Add(nextside, false);
nextside.GroupIndex = curside.GroupIndex;
}
} }
} }
@ -267,27 +283,39 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(prevside.End == curside.Start && prevside.Start != curside.End) if(prevside.End == curside.Start && prevside.Start != curside.End)
{ {
// Add both ways // Add both ways
if(!prevside.NextSides.ContainsKey(curside)) prevside.NextSides.Add(curside, false); if(!prevside.NextSides.ContainsKey(curside))
if(!curside.PreviousSides.ContainsKey(prevside)) curside.PreviousSides.Add(prevside, false); {
prevside.NextSides.Add(curside, false);
prevside.GroupIndex = curside.GroupIndex;
}
if(!curside.PreviousSides.ContainsKey(prevside))
{
curside.PreviousSides.Add(prevside, false);
prevside.GroupIndex = curside.GroupIndex;
}
} }
} }
result.Add(curside); // Add to collection
if(!result.ContainsKey(curside.GroupIndex)) result.Add(curside.GroupIndex, new List<SortedVisualSide>());
result[curside.GroupIndex].Add(curside);
} }
// Try to find the left-most side // Try to find the left-most side
SortedVisualSide start = result[0]; foreach(KeyValuePair<int, List<SortedVisualSide>> pair in result)
foreach (SortedVisualSide side in result)
{ {
if (side.PreviousSides.Count == 0) SortedVisualSide start = pair.Value[0];
foreach(SortedVisualSide side in pair.Value)
{ {
start = side; if(side.PreviousSides.Count == 0) {
break; start = side;
break;
}
} }
}
// Set horizontal offsets... // Set horizontal offsets...
ApplyHorizontalOffset(start, null, true, new Dictionary<int, bool>()); ApplyHorizontalOffset(start, null, true, new Dictionary<int, bool>());
}
return result; return result;
} }

View file

@ -152,7 +152,7 @@
this.cbfitwidth.TabIndex = 2; this.cbfitwidth.TabIndex = 2;
this.cbfitwidth.Text = "Fit width"; this.cbfitwidth.Text = "Fit width";
this.cbfitwidth.UseVisualStyleBackColor = true; this.cbfitwidth.UseVisualStyleBackColor = true;
this.cbfitwidth.CheckedChanged += new System.EventHandler(this.cbfitwidth_CheckedChanged); this.cbfitwidth.CheckedChanged += new System.EventHandler(this.cb_CheckedChanged);
// //
// accept // accept
// //
@ -185,7 +185,7 @@
this.cbfitheight.TabIndex = 8; this.cbfitheight.TabIndex = 8;
this.cbfitheight.Text = "Fit height"; this.cbfitheight.Text = "Fit height";
this.cbfitheight.UseVisualStyleBackColor = true; this.cbfitheight.UseVisualStyleBackColor = true;
this.cbfitheight.CheckedChanged += new System.EventHandler(this.cbfitheight_CheckedChanged); this.cbfitheight.CheckedChanged += new System.EventHandler(this.cb_CheckedChanged);
// //
// cbfitconnected // cbfitconnected
// //
@ -196,6 +196,7 @@
this.cbfitconnected.TabIndex = 9; this.cbfitconnected.TabIndex = 9;
this.cbfitconnected.Text = "Fit across connected surfaces"; this.cbfitconnected.Text = "Fit across connected surfaces";
this.cbfitconnected.UseVisualStyleBackColor = true; this.cbfitconnected.UseVisualStyleBackColor = true;
this.cbfitconnected.CheckedChanged += new System.EventHandler(this.cb_CheckedChanged);
// //
// groupBox2 // groupBox2
// //

View file

@ -209,14 +209,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.Close(); this.Close();
} }
private void cbfitwidth_CheckedChanged(object sender, EventArgs e) private void cb_CheckedChanged(object sender, EventArgs e)
{
if(blockupdate) return;
UpdateRepeatGroup();
UpdateChanges();
}
private void cbfitheight_CheckedChanged(object sender, EventArgs e)
{ {
if(blockupdate) return; if(blockupdate) return;
UpdateRepeatGroup(); UpdateRepeatGroup();