editor/AdvancedMappingTools/Placement/SteelFrameEditor.cs

Editor placement tool for steel frames. Extends PathEditor, passes the drawn ground path and settings to SteelFrameGenerator, and shows a mesh preview before placing columns, beams, base plates and bracing via PartTool.

namespace AdvancedMappingTools;

/// <summary>
/// Draws the line of a steel frame and builds columns, a beam, base plates and bracing
/// along it. Height comes from the settings, the path only gives the ground line.
/// </summary>
[ToolCategory( "Buildings" )]
[Title( "Steel Frame" ), Icon( "construction" )]
public sealed class SteelFrameEditor : PathEditor
{
	public override IReadOnlySet<string> UnusedOptions { get; } = new HashSet<string> { "CurveSegments", "Variation", "Smooth" };

	readonly SteelFrameGenerator _generator = new();

	public SteelFrameEditor( PrimitiveTool tool ) : base( tool ) { }

	public SteelFrameSettings Settings { get; } = new();

	public override object ExtraSettings => Settings;

	protected override int MinPoints => 2;

	protected override bool PlacesObjects => true;

	protected override bool AllowsHeight => true;

	/// <summary>
	/// A frame is straight bays between columns, so no curve handles.
	/// </summary>
	protected override bool UsesBends => false;

	protected override IEnumerable<string> Hints =>
	[
		"Click: place a point",
		"Shift + drag a point: raise or lower it",
		"Enter: create, Esc: stop"
	];

	protected override void BuildMesh( MeshKit kit ) { }

	void Prepare()
	{
		Settings.Path = Curve();
		Settings.SteelMaterial = PartTool.Pick( Settings.SteelMaterial, SurfaceMaterial );
		Settings.BaseMaterial = PartTool.Pick( Settings.BaseMaterial, TrimMaterial );
	}

	protected override PolygonMesh BuildPreview()
	{
		Prepare();

		return PartService.Plan( _generator, Settings ).Flatten( new Transform( Vector3.Zero, Rotation.Identity ) );
	}

	protected override void PlaceObjects()
	{
		Prepare();

		PartTool.Place( _generator, Settings, new Transform( Vector3.Zero, Rotation.Identity ) );
	}
}