.wind Open Winding-Program Format — Specification¶
This is the normative specification for .wind, an open, JSON-based interchange
format that defines filament-winding patterns for composite manufacturing: mandrel
geometry, tow material properties, and a sequence of winding layers. It is intended
for any tool that produces or consumes winding programs, not only FiberPath.
| Status | Normative, stable within major version 1 |
| Current version | 1.3 (the schemaVersion field; see changelog) |
| Media type | application/vnd.fiberpath.wind+json (conventional; not IANA-registered) |
Canonical JSON Schema $id |
https://fiberpath.org/schemas/wind/1/wind.schema.json (major-versioned) |
| Customary extension | .wind |
The format is machine-checkable: the canonical JSON Schema above is generated from
the Pydantic models in fiberpath/config/schemas.py and is
the authoritative structural contract. This document is normative for the semantics and
the conformance requirements that the schema alone cannot express.
Conventions¶
The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY in this document are to be interpreted as described in RFC 2119.
Conformance¶
A conforming document is a JSON document that validates against the canonical JSON Schema for its major version and additionally satisfies the semantic rules in Validation Rules.
A conforming producer (writer):
- MUST emit a document that validates against the canonical schema;
- SHOULD set
schemaVersionto the minor version whose fields it uses; - MUST NOT rely on field ordering for meaning.
A conforming consumer (reader):
- MUST accept any document whose
schemaVersionshares its supported major version, including unknown minor versions (forward compatibility within the major); - MUST treat an absent
schemaVersionas1.0; - MUST reject a document whose
schemaVersionmajor exceeds the one it supports; - SHOULD be tolerant: ignore unknown object members rather than failing, so that additive minor revisions remain readable.
Schema version and compatibility policy¶
Current schema version: 1.3.
The format evolves additively within a major version: a minor revision MAY add
optional fields or layer/surface types, MUST NOT remove or repurpose existing ones, and
MUST NOT change the meaning of an existing document. Because revisions are additive, the
canonical $id is major-only (.../wind/1/...) — every 1.x document validates
against it, and the schemaVersion field carries the minor. A breaking change bumps
the major and mints a new $id (.../wind/2/...). See the changelog.
File Structure¶
A .wind file is a JSON document with the following top-level structure:
{
"schemaVersion": "1.0",
"mandrelParameters": { ... },
"towParameters": { ... },
"defaultFeedRate": 2000,
"layers": [ ... ]
}
Top-Level Fields¶
schemaVersion (optional)¶
- Type:
string - Default:
"1.0" - Description: Version of the
.windfile format schema. Allows for future format evolution and backwards compatibility detection.
mandrelParameters (required)¶
- Type:
object - Description: Physical parameters of the mandrel (the part being wound)
Fields:
diameter(required): Mandrel outer diameter in mm (must be > 0). For a cone, this is the large end atz = 0.windLength(required): Length of the winding area in mm (must be > 0)endDiameter(optional, 1.1+): Outer diameter in mm at the far end (z = windLength). When set belowdiameter, the mandrel is a reducing cone (frustum); omit it (or set it equal todiameter) for a cylinder.profile(optional, 1.2+): a discriminated object selecting a non-developable surface of revolution — currently{ "type": "vonKarman" }(a Von Kármán / LD-Haack nose). The base radius isdiameter/2 and the axial length iswindLength(the profile carries no duplicated dimensions). Mutually exclusive withendDiameter(a profile fully defines the surface).
Example (cylinder):
"mandrelParameters": {
"diameter": 150,
"windLength": 800
}
Example (cone / frustum):
"mandrelParameters": {
"diameter": 98,
"windLength": 120,
"endDiameter": 54
}
Cones (developable surfaces)¶
A cone, like a cylinder, is developable: it unrolls to a flat sector, so a
winding path is closed-form (no ODE/friction solver). Helical layers on a cone
are wound as geodesics (Clairaut's relation r · sin α = const): the wind
angle is anchored at the large end (diameter, z = 0) and the achieved
fiber angle increases toward the small end. Current limits:
- Reducing frustum only —
endDiametermust be< diameter(mount the large end atz = 0). - Helical (and skip) layers only — a hoop layer on a cone is rejected (a 90° hoop is not a geodesic).
- Reachability — a wind angle too steep for the taper is rejected: the geodesic must be able to reach the small end (
diameter · sin α ≤ endDiameter).
Profiles (non-developable surfaces)¶
A profile selects a non-developable surface of revolution (nonzero Gaussian
curvature — it does not unroll flat), so a helical path is no longer a straight
line. The engine integrates the geodesic (Clairaut) relation numerically over the
curved meridian. Currently one profile is defined:
vonKarman— the Von Kármán (LD-Haack) nose. Radius runs fromdiameter/2 at the base (z = 0) to 0 at the tip (z = windLength). A geodesic turns around at the Clairaut radiusC = (diameter/2) · sin α, so it cannot reach the tip: a helical layer leaves an expected bare polar cap of diameter ≈2C, which the planner reports as a G-code comment. Full tip coverage requires non-geodesic winding (a later version). Helical (and skip) layers only; a hoop on a profile is rejected.
Known approximation (cones and profiles). Nominal time/tow metrics use the constant base
diameterfor the mandrel arc length, so on a curved surface the tow length is an approximation that does not reflect the z-varying radius. Toolpath geometry (the emitted coordinates) is exact; only the summary metrics approximate.
towParameters (required)¶
- Type:
object - Description: Material properties of the fiber tow (carbon fiber, fiberglass, etc.)
Fields:
width(required): Tow width in mm (must be > 0)thickness(required): Tow thickness in mm (must be > 0)
Example:
"towParameters": {
"width": 12,
"thickness": 0.25
}
defaultFeedRate (required)¶
- Type:
number - Description: Default feed rate for winding operations in mm/min (must be > 0)
- Example:
2000
layers (required)¶
- Type:
array - Description: Sequential list of winding layers to apply. Each layer is one of three types:
hoop,helical, orskip.
Layer Types¶
Layers are discriminated by the windType field. Each layer type has specific required and optional fields.
Hoop Layer¶
A hoop layer winds perpendicular to the mandrel axis (90° angle). Used for circumferential reinforcement.
Required Fields:
windType: Must be"hoop"
Optional Fields:
terminal(default:false): Whether this is a terminal layer (first or last layer with special handling)
Example:
{
"windType": "hoop",
"terminal": false
}
Use Cases:
- Pressure vessel end caps
- Circumferential reinforcement
- First/last layers of a winding pattern
Helical Layer¶
A helical layer winds at a specified angle, creating a spiral pattern around the mandrel. This is the most complex layer type with geometric constraints.
Required Fields:
windType: Must be"helical"windAngle: Wind angle in degrees (0° < angle ≤ 90°)patternNumber: Number of circuits in the pattern (integer ≥ 1)skipIndex: Skip index for pattern generation (integer ≥ 1, must be coprime withpatternNumber)lockDegrees: Lock rotation in degrees (must be > 0). WhenpatternNumber > 1, this value must also satisfy the coverage compatibility conditions described under Geometric Constraints below.leadInMM: Lead-in distance in mm (must be > 0)leadOutDegrees: Lead-out rotation in degrees (must be > 0)
Optional Fields:
frictionLambda(default:0, schemaVersion 1.3+): Non-geodesic friction ratio λ = k_g/k_n for the laid tow.0winds the geodesic (leaving the expected bare polar cap);> 0lets the pass deviate from the geodesic and climb past the turnaround toward a Von Kármán tip, laying deeper (a smaller bare cap) as λ rises. It must not exceed the machine slip limit μ (slipLimitin the machine profile, default0.2) — a higher value would slip and is rejected. Only meaningful on a Von Kármánprofilemandrel; a non-zero value on a cylinder or cone is rejected. Calibrate empirically: μ depends on fibre, resin, tension, and speed, so start conservative and raise λ toward the μ your setup actually holds. Note the turnaround dwell is a separate limit — when it exceeds μ the laying reaches the cap but the reversal needs 4th-axis delivery (reported by the planner).skipInitialNearLock(default:false): Whether to suppress the initial near-lock mandrel pre-rotation at the start of this layer.
Before the first circuit of a helical layer, the planner normally performs an initial near-lock move: it rotates the mandrel by lockDegrees and re-zeros the rotational position there. This ensures the first circuit starts from the same rotational reference point that all subsequent circuits establish at their turn-around. Without it, the first circuit would begin from whatever position the mandrel is currently at, causing the first and remaining circuits to be rotationally inconsistent.
false(default): Perform the initial near-lock move. Use this for standalone layers or the first helical layer in a sequence.true: Skip the initial near-lock move. Use this when the preceding layer (e.g., aSkipLayeror prior helical layer) has already left the mandrel at the correct rotational reference, avoiding a redundant over-rotation.
Geometric Constraints:
- Coprime Check:
skipIndexandpatternNumbermust be coprime (GCD = 1) to ensure full coverage - Circuit Divisibility: The calculated number of circuits must be evenly divisible by
patternNumberfor valid pattern generation - Wind Angle: Must be between 0° (exclusive) and 90° (inclusive)
- lockDegrees Coverage Compatibility (when
patternNumber > 1): The net mandrel advance per complete circuit is(2 × lockDegrees) mod 360°. Two conditions must hold: - Condition 1 — divisibility:
(2 × lockDegrees) mod (360 / patternNumber)must equal 0. Equivalently,lockDegreesmust be a multiple of180 / patternNumber(e.g. forpatternNumber: 3→ multiples of 60°; forpatternNumber: 4→ multiples of 45°). - Condition 2 — non-aliasing: The resulting intra-pattern slot stride must be coprime with
patternNumber. This prevents all in-pattern circuits from aliasing onto the same groove even when Condition 1 is satisfied. - The validator reports the nearest valid
lockDegreesvalues when either condition fails.
Parameter Meaning (Quick Guide):
windAngle: Fiber direction relative to mandrel axis. This is the normative wind-angle convention across FiberPath — measured from the mandrel axis (the meridian), with0°axial and90°hoop. A hoop layer is thewindAngle → 90°limit of a helical layer.patternNumber: Number of helical bands in the repeating patternskipIndex: Band-to-band stride each circuit; must be coprime withpatternNumberlockDegrees: Additional mandrel rotation at each turn-around (lock) point. Controls the angular spacing between successive circuits — must be a multiple of180 / patternNumber(Condition 1) and produce a slot stride coprime withpatternNumber(Condition 2). See Geometric Constraints above.leadInMM/leadOutDegrees: Entry and exit transition motions for smoother placement
Example:
{
"windType": "helical",
"windAngle": 45,
"patternNumber": 3,
"skipIndex": 1,
"lockDegrees": 540,
"leadInMM": 5,
"leadOutDegrees": 10,
"skipInitialNearLock": false
}
Common Issues:
- If validation fails because circuits are not divisible by
patternNumber, adjust either: - The wind angle (changes circuit count)
- The pattern number (must divide evenly into circuit count)
- The mandrel diameter or wind length
- If validation fails because
lockDegreesis incompatible withpatternNumber, the error message suggests the nearest valid values. As a rule:lockDegreesmust be a multiple of180 / patternNumber. For three-band patterns (patternNumber: 3), use multiples of 60° such as 180°, 360°, or 540°.
Use Cases:
- Pressure vessel cylindrical sections
- Angled reinforcement (±45° for shear resistance)
- Angled helical reinforcement patterns
Skip Layer¶
A skip layer rotates the mandrel without winding, allowing for pattern repositioning or creating gaps.
Required Fields:
windType: Must be"skip"mandrelRotation: Rotation amount in degrees
Example:
{
"windType": "skip",
"mandrelRotation": 180
}
Use Cases:
- Pattern alignment between layers
- Creating intentional gaps
- Repositioning between layers
Validation Rules¶
The schema enforces the following validation rules:
Type Validation¶
- All numeric fields must be numbers (integer or float as specified)
- Boolean fields must be
trueorfalse - String fields must be strings
- Arrays must contain items of the correct type
Range Validation¶
- All dimensions (diameter, windLength, width, thickness, etc.) must be greater than zero (exclusive minimum)
- Wind angles must be in the range (0°, 90°]
- Pattern numbers and skip indices must be positive integers
Structural Validation¶
- All required fields must be present
- Layer discriminator (
windType) must be one of:"hoop","helical","skip" - Each layer type must include its required fields
Geometric Validation (CLI)¶
The CLI performs additional validation beyond the schema:
- Coprime check for helical layers (
gcd(skipIndex, patternNumber) == 1) - Circuit divisibility check for helical patterns
lockDegreescoverage compatibility check for helical layers withpatternNumber > 1(two-condition check: divisibility and non-aliasing)- Terminal layer placement rules
- Physical feasibility checks
Schema Management¶
Schema Generation¶
The JSON Schema is automatically generated from Pydantic models:
cd fiberpath_gui
npm run schema:generate
This command:
- Runs
scripts/generate_schema.pyto extract schema from Python - Generates TypeScript types using
json-schema-to-typescript - Updates
schemas/wind-schema.jsonandsrc/types/wind-schema.ts
Schema Location¶
- JSON Schema:
fiberpath_gui/schemas/wind-schema.json - TypeScript Types:
fiberpath_gui/src/types/wind-schema.ts - Python Models:
fiberpath/config/schemas.py - Validation:
fiberpath/config/validator.py
Backwards compatibility¶
The compatibility guarantees are normative and stated in
Schema version and compatibility policy and
Conformance: additive-only within a major version, tolerant readers,
absent schemaVersion treated as 1.0. The changelog below records each minor.
Format changelog¶
Additive-only within major version 1; tolerant readers ignore unknown fields, and
a missing schemaVersion is treated as 1.0.
- 1.3 — added optional
frictionLambdaon helical layers for non-geodesic (friction-assisted) winding on a Von Kármán profile:0(the default) is the geodesic path,> 0lets the pass climb past the geodesic turnaround toward the tip, up to the machine slip limit μ (slipLimitin the machine profile; default0.2). The planner rejectsfrictionLambda > μ("would slip") and a non-zero value on a cylinder/cone (non-geodesic winding requires a profile). Files omittingfrictionLambdaare unchanged. The turnaround dwell is reported and, when it exceeds μ, flagged as needing 4th-axis delivery (a future capability). - 1.2 — added optional
mandrelParameters.profile(a discriminated{ "type": "vonKarman" }) for non-developable surfaces of revolution, starting with the Von Kármán (LD-Haack) nose. Helical layers follow a numeric geodesic and leave an expected bare polar cap near the tip (reported by the planner). Mutually exclusive withendDiameter. Files omittingprofileare unchanged 1.0/1.1. - 1.1 — added optional
mandrelParameters.endDiameterfor reducing cones (frustums); helical layers on a cone are wound as geodesics. Files omittingendDiameterare unchanged 1.0 cylinders. - 1.0 — initial schema: discriminated layer types (hoop / helical / skip) on a cylinder.
Example Files¶
Minimal Hoop Pattern¶
{
"schemaVersion": "1.0",
"mandrelParameters": {
"diameter": 150,
"windLength": 800
},
"towParameters": {
"width": 12,
"thickness": 0.25
},
"defaultFeedRate": 2000,
"layers": [
{
"windType": "hoop",
"terminal": false
}
]
}
Multi-Layer Helical Pattern¶
{
"schemaVersion": "1.0",
"mandrelParameters": {
"diameter": 150,
"windLength": 800
},
"towParameters": {
"width": 12,
"thickness": 0.25
},
"defaultFeedRate": 2000,
"layers": [
{
"windType": "hoop",
"terminal": false
},
{
"windType": "helical",
"windAngle": 45,
"patternNumber": 3,
"skipIndex": 1,
"lockDegrees": 540,
"leadInMM": 5,
"leadOutDegrees": 10,
"skipInitialNearLock": false
},
{
"windType": "skip",
"mandrelRotation": 180
},
{
"windType": "helical",
"windAngle": 45,
"patternNumber": 3,
"skipIndex": 1,
"lockDegrees": 540,
"leadInMM": 5,
"leadOutDegrees": 10,
"skipInitialNearLock": true
},
{
"windType": "hoop",
"terminal": true
}
]
}
Related Documentation¶
- Architecture: System design and component interaction
- API Documentation: REST API endpoints for validation and planning
- Concepts: Winding theory and geometric calculations
Validation Tools¶
CLI Validation¶
fiberpath validate input.wind
GUI Validation¶
The GUI automatically validates .wind files:
- On file open (before loading into editor)
- Before planning (before sending to CLI)
- On save (before writing to disk)
Validation errors are displayed with specific field paths and messages.
Python API¶
from fiberpath.config.validator import validate_wind_definition
errors = validate_wind_definition(wind_dict)
if errors:
for error in errors:
print(f"Error in {error.field}: {error.message}")
Future Enhancements¶
Potential additions to future schema versions:
- Custom layer strategies beyond hoop/helical/skip
- Advanced material properties (resin content, fiber density)
- Multi-tow configurations
- Temperature and cure profiles
- Process parameters (tension, speed profiles)
Changes will maintain backwards compatibility through the schemaVersion field.