Editor/Porch/ArchPorchTrim.cs

Editor code for porch trim and flashing generation. It adds a ceiling slab and a frieze around a porch footprint, and emits flashing trim where a porch roof meets the wall using band sections along each wall.

File Access
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;

namespace Sunless.Architecture;

public static partial class ArchPorchGen
{
	// A frieze caps the seam where the boards die into the wall.
	static void Ceiling( ArchMesh canvas, ArchPorchShape shape, ArchKit kit, ArchBrush boards, ArchBrush trim )
	{
		var bite = ArchContact.Bite( kit );
		var thickness = MathF.Max( 1f, kit.PorchCeilingThickness );

		foreach ( var loop in ArchFootprint.Grow( new[] { shape.Footprint }, bite ) )
		{
			ArchFloorGen.Slab( canvas, loop, null, shape.Ceiling - thickness, shape.Ceiling, boards );
		}

		var height = MathF.Max( 2f, kit.PorchFriezeHeight );
		var depth = MathF.Max( 0.5f, kit.PorchFriezeDepth );

		foreach ( var wall in shape.Walls )
		{
			ArchBandSection.Between( -bite, depth, shape.Ceiling - thickness - height, shape.Ceiling - thickness + bite )
				.Emit( canvas, ArchRunPath.Between( wall.From, wall.To ), trim );
		}
	}

	// Covers the raw seam where the roof's high edge dies in the brick.
	static void Flashing( ArchMesh canvas, ArchPorchShape shape, ArchPorchPart porch, ArchBuilding building, ArchKit kit, ArchBrush brush )
	{
		var roof = building.Roofs.FirstOrDefault( part => part.Id == porch.RoofId );

		if ( roof is null )
		{
			return;
		}

		var thickness = roof.Thickness > 0f ? roof.Thickness : kit.RoofThickness;
		var slope = ArchRoofPlane.Slope( roof );
		var height = MathF.Max( 2f, kit.PorchFlashingHeight );
		var depth = MathF.Max( 0.5f, kit.PorchFriezeDepth );
		var bite = ArchContact.Bite( kit );

		foreach ( var wall in shape.Walls )
		{
			var deck = roof.BaseHeight + slope * (wall.Depth + roof.Overhang) + thickness;

			ArchBandSection.Between( -bite, depth, deck - 1f, deck + height )
				.Emit( canvas, ArchRunPath.Between( wall.From, wall.To ), brush );
		}
	}

}