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.
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 );
}
}
}