Editor-side report generator for wall geometry. It formats debug text describing each wall in a plan including start/end, length, direction, thickness, join info, grid snapping and baseboard/head measurements.
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;
namespace Sunless.Architecture;
public static partial class ArchReport
{
// The same numbers the generator reads, so what is printed is what is built.
public static string WallDebug( ArchPlan plan, ArchKit kit )
{
var grid = new ArchGridService();
// The generator resolves across the whole storey, so a wall landing on the building next door
// joins. Reading a building at a time made the report disagree with what was built at exactly
// the joins that are hardest to settle by eye.
var connections = new ArchConnectionService( plan, kit );
var lines = new List<string>
{
"# Architecture wall debug",
$"kit {kit.Name} grid {grid.BaseSize:0.##} wall thickness {kit.WallThickness:0.##}",
""
};
foreach ( var building in plan.Buildings )
{
foreach ( var room in building.Rooms )
{
foreach ( var wall in room.Walls )
{
lines.AddRange( WallDebug( connections, building, room, wall, grid, kit ) );
}
}
}
return string.Join( "\n", lines );
}
static IEnumerable<string> WallDebug( ArchConnectionService connections, ArchBuilding building, ArchRoom room, ArchWall wall, ArchGridService grid, ArchKit kit )
{
var thickness = ArchWallSection.Thickness( wall, kit );
var height = ArchWallSection.Height( wall, room, kit );
var join = connections.JoinWall( wall, room, thickness );
var foot = join.Foot( kit.BaseboardDepth );
var head = join.Head( kit.BaseboardDepth );
var from = join.From;
var to = join.To;
var side = wall.Normal * (thickness * 0.5f);
var bandStart = wall.Start + wall.Direction * join.StartExtend - side;
var bandEnd = wall.Start + wall.Direction * join.EndExtend - side;
var bandTopEnd = wall.Start + wall.Direction * join.EndMitre + side;
var bandTopStart = wall.Start + wall.Direction * join.StartMitre + side;
return new[]
{
$"{building.Name}/{room.Name}/{ArchNames.Wall( wall )} (id {wall.Id})",
$" start ({wall.Start.x:0.##},{wall.Start.y:0.##}) end ({wall.End.x:0.##},{wall.End.y:0.##})"
+ $" len {wall.Length:0.##} dir ({wall.Direction.x:0.##},{wall.Direction.y:0.##})"
+ $" thickness {thickness:0.##} height {height:0.##}"
+ $" exterior {wall.Exterior} baseboard {wall.Baseboard} cap {wall.Cap}",
$" grid start {Grid( grid, wall.Start.x )},{Grid( grid, wall.Start.y )} end {Grid( grid, wall.End.x )},{Grid( grid, wall.End.y )}",
$" join start extend {join.StartExtend:0.##} joined {join.StartJoined} capped {join.StartCapped} mitre {join.StartMitre:0.##}"
+ $" | end extend {join.EndExtend:0.##} joined {join.EndJoined} capped {join.EndCapped} mitre {join.EndMitre:0.##}"
+ $" landings [{string.Join( ", ", join.Landings.Select( value => value.ToString( "0.##" ) ) )}]",
$" board foot {foot.Inner:0.##}/{foot.Outer:0.##} {foot.Stop} | head {head.Inner:0.##}/{head.Outer:0.##} {head.Stop}",
$" band along {from:0.##}..{to:0.##} corners ({bandStart.x:0.##},{bandStart.y:0.##}) ({bandEnd.x:0.##},{bandEnd.y:0.##})"
+ $" ({bandTopEnd.x:0.##},{bandTopEnd.y:0.##}) ({bandTopStart.x:0.##},{bandTopStart.y:0.##})",
""
};
}
static string Grid( ArchGridService grid, float value ) => OnGrid( value, grid.BaseSize ) ? "on" : "off";
static bool OnGrid( float value, float size ) => MathF.Abs( value - ArchGridService.Snap( value, size ) ) < 0.01f;
static string Say( Vector3 point ) => $"{point.x:0.#},{point.y:0.#},{point.z:0.#}";
}