"""Schema dataclasses for open section-curve definitions."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Literal, TypeAlias
from buffalo_core.schema import SchemaChoice, SchemaField
from .common import Point2DSpec
from .constants import POINT2D_TUPLE_LENGTH
[docs]
@dataclass(slots=True)
class AirfoilCamberApproximationSpec:
"""
Approximation settings for airfoil-derived camber curves.
Notes
-----
These settings are used only when the referenced airfoil runtime does
not expose an exact native camber curve.
Airfoil families with exact camber ignore these controls.
"""
#: Shared surface-local spacing rule for approximate camber extraction.
spacing: Literal["uniform", "cosine"] = field(
default="cosine",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Spacing",
order=10,
short_help="Shared surface-local spacing for approximation.",
default="cosine",
choices=(
SchemaChoice(value="uniform", label="Uniform"),
SchemaChoice(value="cosine", label="Cosine"),
),
notes=(
"Used only when the referenced airfoil family does not "
"provide exact camber."
),
).to_metadata(),
)
#: Number of shared surface samples used for approximate extraction.
num_points: int = field(
default=81,
metadata=SchemaField(
value_kind="integer",
required=False,
label="Sample Count",
order=20,
short_help="Shared surface samples used for approximation.",
default=81,
minimum=2,
notes=(
"Used only when the referenced airfoil family does not "
"provide exact camber."
),
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class AirfoilCamberCurveSpec:
"""
Open camber curve derived from a named airfoil definition.
Notes
-----
This schema keeps the camber curve linked to the source airfoil so GUI
and analysis workflows can reuse the existing airfoil definition without
restating family-specific camber inputs.
"""
#: Schema discriminator for an airfoil-derived camber curve.
type: Literal["airfoil_camber"] = field(
default="airfoil_camber",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help="Schema discriminator for an airfoil-derived camber.",
default="airfoil_camber",
choices=(
SchemaChoice(
value="airfoil_camber",
label="Airfoil Camber",
),
),
).to_metadata(),
)
#: Name of the referenced airfoil in the top-level ``airfoils`` map.
airfoil: str = field(
default="",
metadata=SchemaField(
value_kind="string",
required=False,
label="Airfoil",
order=20,
short_help="Named source airfoil used to derive the camber line.",
default="",
format_hint="name from the top-level airfoils map",
notes="Validation requires a non-empty reference name.",
).to_metadata(),
)
#: Approximation controls for families without exact native camber.
approximation: AirfoilCamberApproximationSpec = field(
default_factory=AirfoilCamberApproximationSpec,
metadata=SchemaField(
value_kind="object",
required=False,
label="Approximation",
order=30,
short_help="Fallback controls for approximate camber extraction.",
item_kind="AirfoilCamberApproximationSpec",
notes=(
"Ignored when the referenced airfoil runtime exposes exact "
"camber."
),
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class SplineCurveSpec:
"""
Directly authored spline-backed open curve definition.
Notes
-----
The first supported schema slice stores only Bezier control points and
keeps the runtime neutral enough for future non-Bezier spline backends.
"""
#: Schema discriminator for a spline-backed open curve.
type: Literal["spline_curve"] = field(
default="spline_curve",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help="Schema discriminator for a spline-backed open curve.",
default="spline_curve",
choices=(
SchemaChoice(
value="spline_curve",
label="Spline Curve",
),
),
).to_metadata(),
)
#: Supported spline representation subtype.
representation: Literal["bezier"] = field(
default="bezier",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Representation",
order=20,
short_help="Spline representation subtype for open curves.",
default="bezier",
choices=(SchemaChoice(value="bezier", label="Bezier"),),
).to_metadata(),
)
#: Open-curve control points ordered from ``u = 0`` to ``u = 1``.
control_points: list[Point2DSpec] = field(
default_factory=list,
metadata=SchemaField(
value_kind="list",
required=False,
label="Control Points",
order=30,
short_help="Bezier control points from start to end.",
min_items=2,
item_kind="Point2DSpec",
tuple_length=POINT2D_TUPLE_LENGTH,
format_hint="[(x, y), ...]",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class PolylineCurveSpec:
"""
Directly authored point-to-point open curve definition.
Notes
-----
This family stores explicit vertices and resolves to a piecewise-linear
runtime curve, which makes it the lightest-weight authoring path for
simple walls or guide geometry.
"""
#: Schema discriminator for a point-to-point open curve.
type: Literal["polyline_curve"] = field(
default="polyline_curve",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help="Schema discriminator for a point-to-point open curve.",
default="polyline_curve",
choices=(
SchemaChoice(
value="polyline_curve",
label="Polyline Curve",
),
),
).to_metadata(),
)
#: Ordered vertices from curve start to curve end.
points: list[Point2DSpec] = field(
default_factory=list,
metadata=SchemaField(
value_kind="list",
required=False,
label="Points",
order=20,
short_help="Ordered curve vertices from start to end.",
min_items=2,
item_kind="Point2DSpec",
tuple_length=POINT2D_TUPLE_LENGTH,
format_hint="[(x, y), ...]",
).to_metadata(),
)
CurveDefinitionSpec: TypeAlias = ( # noqa: UP040
AirfoilCamberCurveSpec | SplineCurveSpec | PolylineCurveSpec
)
__all__ = [
"AirfoilCamberApproximationSpec",
"AirfoilCamberCurveSpec",
"CurveDefinitionSpec",
"PolylineCurveSpec",
"SplineCurveSpec",
]