editor/AdvancedMappingTools/Procedural/StackedWallOpenings.cs

One method of the editor's procedural connected wall generator. Builds a single wall layer: clamps each opening to the section, splits the section into x/z cells around the hole bounds, skips cells inside a hole, clamps the bottom of each cell to the plinth floor, adds wall infill prisms per shape piece, then places doors and windows for the remaining openings.

namespace AdvancedMappingTools;
public sealed partial class ConnectedWallGenerator
{
	static PartPlan LayeredSection( ConnectedWallSettings s, GenContext context, WallShape shape, WallSection section, int index, float z0, float z1, Material material, WallOpeningSpec[] openings )
	{
		var id = $"section{index:00}";
		var group = context.Group( id, $"Wall Section {index + 1}", "Wall", WallCategory );
		var holes = openings.Select( o => (Spec: o, From: MathF.Max( o.Along - o.Width * .5f, section.From + PierClearance ), To: MathF.Min( o.Along + o.Width * .5f, section.To - PierClearance ), Low: Math.Clamp( z0 + o.Sill, z0, z1 ), High: Math.Clamp( z0 + o.Sill + o.Height, z0, z1 )) ).Where( h => h.To - h.From >= 1 && h.High - h.Low >= 1 ).ToArray();
		var xs = holes.SelectMany( h => new[] { h.From, h.To } ).Append( section.From ).Append( section.To ).Distinct().OrderBy( x => x ).ToArray();
		for ( var x = 0; x + 1 < xs.Length; x++ )
		{
			var from = xs[x];
			var to = xs[x + 1];
			if ( to - from < MinimumPanel )
				continue;
			var mid = (from + to) * .5f;
			var active = holes.Where( h => mid > h.From && mid < h.To ).ToArray();
			var zs = active.SelectMany( h => new[] { h.Low, h.High } ).Append( z0 ).Append( z1 ).Distinct().OrderBy( z => z ).ToArray();
			for ( var z = 0; z + 1 < zs.Length; z++ )
			{
				var low = zs[z];
				var high = zs[z + 1];
				var center = (low + high) * .5f;
				if ( active.Any( h => center > h.Low && center < h.High ) )
					continue;
				// With a plinth the wall stands on it instead of reaching down through it.
				low = MathF.Max( low, Floor( s, z0 ) );
				if ( high - low < MinimumPanel )
					continue;
				var piece = 0;
				foreach ( var(start, end)in shape.Pieces( from, to ) )
				{
					group.Add( context.Solid( $"{id}/cell{x:00}_{z:00}_{piece++}", "Wall Infill", "WallPanel", WallCategory, material, kit => kit.Prism( shape.Outline( section, start, end ), low, high ) ) );
				}
			}
		}

		for ( var i = 0; i < holes.Length; i++ )
		{
			var h = holes[i];
			if ( h.Spec.Door )
				group.Add( Door( s, shape, context, $"{id}/door{i}", i, h.From, h.To, h.Low, h.High - h.Low, context.Material( s.WindowMaterial ), material, h.Spec ) );
			else if ( h.Spec.Window && s.Windows )
				group.Add( Window( s, context, shape, $"{id}/window{i}", i, h.From, h.To, h.Low, h.High - h.Low, context.Material( s.WindowMaterial ), context.Material( s.GlassMaterial ), h.Spec ) );
		}

		return group;
	}
}