@willcgage/module-schematic 0.97.0 → 0.98.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +89 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -1
- package/dist/index.d.ts +36 -1
- package/dist/index.js +89 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -677,6 +677,12 @@ interface ModuleFootprintInput {
|
|
|
677
677
|
/** A balloon / return loop — the centre-line turns back on itself, so its far
|
|
678
678
|
* end is the THROAT, not an endplate; only endplate A's face is emitted (#loop). */
|
|
679
679
|
loop?: boolean;
|
|
680
|
+
/**
|
|
681
|
+
* The document already places track along a main (see {@link
|
|
682
|
+
* moduleCenterline}). Set from the doc's own `tracks`; without it a module
|
|
683
|
+
* whose track was authored before it had a geometry draws as a bare board.
|
|
684
|
+
*/
|
|
685
|
+
hasPlacedTrack?: boolean;
|
|
680
686
|
/** Axial endplate configs (A first, then B), same as
|
|
681
687
|
* {@link ModuleGeometryInput.endplateConfigs}. `"none"` at B means the module
|
|
682
688
|
* presents no far endplate, so no face is emitted there (#184/#191). */
|
|
@@ -2744,6 +2750,35 @@ declare function snapPiece(moving: TrackPiece, others: TrackPiece[], library?: T
|
|
|
2744
2750
|
* owner's curve to reach something is not a fit, it is a guess.
|
|
2745
2751
|
*/
|
|
2746
2752
|
declare function fitFlexBetween(piece: TrackPiece, others: TrackPiece[], library?: TrackPart[], withinInches?: number): TrackPiece | null;
|
|
2753
|
+
/** A run cut in two to let a piece in. */
|
|
2754
|
+
interface RunInsertion {
|
|
2755
|
+
/** The whole set: the host shortened, the new piece, and the remainder. */
|
|
2756
|
+
pieces: TrackPiece[];
|
|
2757
|
+
/** The run that was cut, and the piece that went into it. */
|
|
2758
|
+
hostId: string;
|
|
2759
|
+
insertedId: string;
|
|
2760
|
+
}
|
|
2761
|
+
/**
|
|
2762
|
+
* Drop a piece ONTO a run and cut the run to take it.
|
|
2763
|
+
*
|
|
2764
|
+
* ⭐ Will, 2026-07-27: *"When I drop a turnout on the track, it should cut the
|
|
2765
|
+
* track there and automatically snap to the new joints."* Snapping alone cannot
|
|
2766
|
+
* do this: the middle of a run has no open joint, so there is nothing to snap
|
|
2767
|
+
* TO — the joints have to be made by cutting, which is exactly what a builder
|
|
2768
|
+
* does with a razor saw.
|
|
2769
|
+
*
|
|
2770
|
+
* ⚠️ ONLY FLEX CAN BE CUT. A turnout or a sectional piece is a moulding: you
|
|
2771
|
+
* cannot saw one in half and have two of anything. Dropping onto one is refused
|
|
2772
|
+
* rather than fudged.
|
|
2773
|
+
*
|
|
2774
|
+
* ⚠️ AND THE PIECE HAS TO FIT. It consumes length along the run — a #7 is six
|
|
2775
|
+
* inches of it — so an insertion that would run off the end is refused instead
|
|
2776
|
+
* of silently producing a remainder of negative length.
|
|
2777
|
+
*/
|
|
2778
|
+
declare function insertIntoRun(pieces: TrackPiece[], fresh: TrackPiece, at: {
|
|
2779
|
+
x: number;
|
|
2780
|
+
y: number;
|
|
2781
|
+
}, library?: TrackPart[], withinInches?: number): RunInsertion | null;
|
|
2747
2782
|
/** A route the walk found: a continuous run of pieces a train can travel. */
|
|
2748
2783
|
interface GraphRoute {
|
|
2749
2784
|
id: string;
|
|
@@ -3174,4 +3209,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
3174
3209
|
heading: number;
|
|
3175
3210
|
}>;
|
|
3176
3211
|
|
|
3177
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplateEdge, type EndplateEdgePose, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, GENERIC_END_OF_TRACK, type GeometryType, type GraphAnchor, type GraphConflict, type GraphConnection, type GraphDocInput, type GraphDocResult, type GraphRoute, type GraphTurnout, type GraphWalk, type ImportedPart, type IndustryLabelMode, type IndustrySpot, JOINT_SNAP_INCHES, type LanePinch, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OccupiedSpan, type OutlineFace, PINCH_EASE_INCHES, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartGeometry, type PartJoint, type PartJointRole, type PartSegment, type PieceSnap, type PlacedJoint, RAIL_GAUGE_INCHES, type ResolvedAnchor, type ReturnLoopGeometry, type ReturnLoopShape, type RouteSpan, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionEnd, type SectionEndAssessment, type SectionFootprint, type SectionJointAssessment, type SectionRelativePos, type SignalFacing, type SignalSide, type SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackGraph, type TrackPart, type TrackPiece, type TrackRole, type TurnoutClosure, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
|
|
3212
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplateEdge, type EndplateEdgePose, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, GENERIC_END_OF_TRACK, type GeometryType, type GraphAnchor, type GraphConflict, type GraphConnection, type GraphDocInput, type GraphDocResult, type GraphRoute, type GraphTurnout, type GraphWalk, type ImportedPart, type IndustryLabelMode, type IndustrySpot, JOINT_SNAP_INCHES, type LanePinch, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OccupiedSpan, type OutlineFace, PINCH_EASE_INCHES, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartGeometry, type PartJoint, type PartJointRole, type PartSegment, type PieceSnap, type PlacedJoint, RAIL_GAUGE_INCHES, type ResolvedAnchor, type ReturnLoopGeometry, type ReturnLoopShape, type RouteSpan, type RunInsertion, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionEnd, type SectionEndAssessment, type SectionFootprint, type SectionJointAssessment, type SectionRelativePos, type SignalFacing, type SignalSide, type SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackGraph, type TrackPart, type TrackPiece, type TrackRole, type TurnoutClosure, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
|
package/dist/index.d.ts
CHANGED
|
@@ -677,6 +677,12 @@ interface ModuleFootprintInput {
|
|
|
677
677
|
/** A balloon / return loop — the centre-line turns back on itself, so its far
|
|
678
678
|
* end is the THROAT, not an endplate; only endplate A's face is emitted (#loop). */
|
|
679
679
|
loop?: boolean;
|
|
680
|
+
/**
|
|
681
|
+
* The document already places track along a main (see {@link
|
|
682
|
+
* moduleCenterline}). Set from the doc's own `tracks`; without it a module
|
|
683
|
+
* whose track was authored before it had a geometry draws as a bare board.
|
|
684
|
+
*/
|
|
685
|
+
hasPlacedTrack?: boolean;
|
|
680
686
|
/** Axial endplate configs (A first, then B), same as
|
|
681
687
|
* {@link ModuleGeometryInput.endplateConfigs}. `"none"` at B means the module
|
|
682
688
|
* presents no far endplate, so no face is emitted there (#184/#191). */
|
|
@@ -2744,6 +2750,35 @@ declare function snapPiece(moving: TrackPiece, others: TrackPiece[], library?: T
|
|
|
2744
2750
|
* owner's curve to reach something is not a fit, it is a guess.
|
|
2745
2751
|
*/
|
|
2746
2752
|
declare function fitFlexBetween(piece: TrackPiece, others: TrackPiece[], library?: TrackPart[], withinInches?: number): TrackPiece | null;
|
|
2753
|
+
/** A run cut in two to let a piece in. */
|
|
2754
|
+
interface RunInsertion {
|
|
2755
|
+
/** The whole set: the host shortened, the new piece, and the remainder. */
|
|
2756
|
+
pieces: TrackPiece[];
|
|
2757
|
+
/** The run that was cut, and the piece that went into it. */
|
|
2758
|
+
hostId: string;
|
|
2759
|
+
insertedId: string;
|
|
2760
|
+
}
|
|
2761
|
+
/**
|
|
2762
|
+
* Drop a piece ONTO a run and cut the run to take it.
|
|
2763
|
+
*
|
|
2764
|
+
* ⭐ Will, 2026-07-27: *"When I drop a turnout on the track, it should cut the
|
|
2765
|
+
* track there and automatically snap to the new joints."* Snapping alone cannot
|
|
2766
|
+
* do this: the middle of a run has no open joint, so there is nothing to snap
|
|
2767
|
+
* TO — the joints have to be made by cutting, which is exactly what a builder
|
|
2768
|
+
* does with a razor saw.
|
|
2769
|
+
*
|
|
2770
|
+
* ⚠️ ONLY FLEX CAN BE CUT. A turnout or a sectional piece is a moulding: you
|
|
2771
|
+
* cannot saw one in half and have two of anything. Dropping onto one is refused
|
|
2772
|
+
* rather than fudged.
|
|
2773
|
+
*
|
|
2774
|
+
* ⚠️ AND THE PIECE HAS TO FIT. It consumes length along the run — a #7 is six
|
|
2775
|
+
* inches of it — so an insertion that would run off the end is refused instead
|
|
2776
|
+
* of silently producing a remainder of negative length.
|
|
2777
|
+
*/
|
|
2778
|
+
declare function insertIntoRun(pieces: TrackPiece[], fresh: TrackPiece, at: {
|
|
2779
|
+
x: number;
|
|
2780
|
+
y: number;
|
|
2781
|
+
}, library?: TrackPart[], withinInches?: number): RunInsertion | null;
|
|
2747
2782
|
/** A route the walk found: a continuous run of pieces a train can travel. */
|
|
2748
2783
|
interface GraphRoute {
|
|
2749
2784
|
id: string;
|
|
@@ -3174,4 +3209,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
3174
3209
|
heading: number;
|
|
3175
3210
|
}>;
|
|
3176
3211
|
|
|
3177
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplateEdge, type EndplateEdgePose, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, GENERIC_END_OF_TRACK, type GeometryType, type GraphAnchor, type GraphConflict, type GraphConnection, type GraphDocInput, type GraphDocResult, type GraphRoute, type GraphTurnout, type GraphWalk, type ImportedPart, type IndustryLabelMode, type IndustrySpot, JOINT_SNAP_INCHES, type LanePinch, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OccupiedSpan, type OutlineFace, PINCH_EASE_INCHES, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartGeometry, type PartJoint, type PartJointRole, type PartSegment, type PieceSnap, type PlacedJoint, RAIL_GAUGE_INCHES, type ResolvedAnchor, type ReturnLoopGeometry, type ReturnLoopShape, type RouteSpan, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionEnd, type SectionEndAssessment, type SectionFootprint, type SectionJointAssessment, type SectionRelativePos, type SignalFacing, type SignalSide, type SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackGraph, type TrackPart, type TrackPiece, type TrackRole, type TurnoutClosure, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
|
|
3212
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplateEdge, type EndplateEdgePose, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, GENERIC_END_OF_TRACK, type GeometryType, type GraphAnchor, type GraphConflict, type GraphConnection, type GraphDocInput, type GraphDocResult, type GraphRoute, type GraphTurnout, type GraphWalk, type ImportedPart, type IndustryLabelMode, type IndustrySpot, JOINT_SNAP_INCHES, type LanePinch, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OccupiedSpan, type OutlineFace, PINCH_EASE_INCHES, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartGeometry, type PartJoint, type PartJointRole, type PartSegment, type PieceSnap, type PlacedJoint, RAIL_GAUGE_INCHES, type ResolvedAnchor, type ReturnLoopGeometry, type ReturnLoopShape, type RouteSpan, type RunInsertion, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionEnd, type SectionEndAssessment, type SectionFootprint, type SectionJointAssessment, type SectionRelativePos, type SignalFacing, type SignalSide, type SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackGraph, type TrackPart, type TrackPiece, type TrackRole, type TurnoutClosure, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
|
package/dist/index.js
CHANGED
|
@@ -227,7 +227,7 @@ function moduleCenterline(input) {
|
|
|
227
227
|
if (drawn) return samplePath(drawn);
|
|
228
228
|
const chained = sectionedCenterline(input);
|
|
229
229
|
if (chained.length >= 2) return chained;
|
|
230
|
-
if (!input.geometryType) return [];
|
|
230
|
+
if (!input.geometryType && !input.hasPlacedTrack) return [];
|
|
231
231
|
const L = input.lengthInches > 0 ? input.lengthInches : 24;
|
|
232
232
|
const gt = input.geometryType;
|
|
233
233
|
if (gt === "dead_end") return [{ x: 0, y: 0 }];
|
|
@@ -2311,6 +2311,16 @@ function pieceRoutePaths(piece, library = BUILT_IN_TRACK_PARTS) {
|
|
|
2311
2311
|
const len = part.overallLength?.inches ?? BUMPER_DRAWN_INCHES;
|
|
2312
2312
|
return [{ route: ["a", "a"], points: [{ x: at2.x, y: at2.y }, place(len, 0)] }];
|
|
2313
2313
|
}
|
|
2314
|
+
if (part.kind === "curve") {
|
|
2315
|
+
const a = joints.find((j) => j.joint === "a");
|
|
2316
|
+
const b = joints.find((j) => j.joint === "b");
|
|
2317
|
+
if (!a || !b) return out;
|
|
2318
|
+
const pts = flexRunPoints(sectionalArcInches(part), part.radius.inches).map(
|
|
2319
|
+
(q) => place(q.x, q.y)
|
|
2320
|
+
);
|
|
2321
|
+
pts[pts.length - 1] = { x: b.x, y: b.y };
|
|
2322
|
+
return [{ route: ["a", "b"], points: pts }];
|
|
2323
|
+
}
|
|
2314
2324
|
for (const route of geo.routes) {
|
|
2315
2325
|
const a = at(route[0]);
|
|
2316
2326
|
const b = at(route[1]);
|
|
@@ -2541,6 +2551,83 @@ function fitFlexBetween(piece, others, library = BUILT_IN_TRACK_PARTS, withinInc
|
|
|
2541
2551
|
lengthInches: Math.round(len * 1e3) / 1e3
|
|
2542
2552
|
};
|
|
2543
2553
|
}
|
|
2554
|
+
function insertIntoRun(pieces, fresh, at, library = BUILT_IN_TRACK_PARTS, withinInches = 1) {
|
|
2555
|
+
let host = null;
|
|
2556
|
+
let bestD = Infinity;
|
|
2557
|
+
for (const piece of pieces) {
|
|
2558
|
+
const part = library.find((x) => x.id === piece.partId);
|
|
2559
|
+
if (part?.kind !== "flex") continue;
|
|
2560
|
+
for (const { points } of pieceRoutePaths(piece, library))
|
|
2561
|
+
for (let i = 1; i < points.length; i++) {
|
|
2562
|
+
const d = distanceToSegment(at, points[i - 1], points[i]);
|
|
2563
|
+
if (d < bestD) {
|
|
2564
|
+
bestD = d;
|
|
2565
|
+
host = piece;
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
if (!host || bestD > withinInches) return null;
|
|
2570
|
+
const L = host.lengthInches ?? 0;
|
|
2571
|
+
const R = host.radiusInches;
|
|
2572
|
+
const steps = 200;
|
|
2573
|
+
let s = 0;
|
|
2574
|
+
let closest = Infinity;
|
|
2575
|
+
for (let i = 0; i <= steps; i++) {
|
|
2576
|
+
const t = L * i / steps;
|
|
2577
|
+
const local = flexRunEnd(t, R);
|
|
2578
|
+
const world = placeLocal(host, local.x, local.y);
|
|
2579
|
+
const d = Math.hypot(world.x - at.x, world.y - at.y);
|
|
2580
|
+
if (d < closest) {
|
|
2581
|
+
closest = d;
|
|
2582
|
+
s = t;
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
const cutLocal = flexRunEnd(s, R);
|
|
2586
|
+
const cut = placeLocal(host, cutLocal.x, cutLocal.y);
|
|
2587
|
+
const heading = norm360(host.rotationDeg + (host.flipped ? -cutLocal.headingDeg : cutLocal.headingDeg));
|
|
2588
|
+
const placed = { ...fresh, x: cut.x, y: cut.y, rotationDeg: heading };
|
|
2589
|
+
const js = placedJoints([placed], library);
|
|
2590
|
+
const entry = js.find((j) => j.joint === "throat" || j.joint === "a");
|
|
2591
|
+
const exit = js.find((j) => j.joint === "through" || j.joint === "b");
|
|
2592
|
+
if (!entry || !exit) return null;
|
|
2593
|
+
const body = Math.hypot(exit.x - entry.x, exit.y - entry.y);
|
|
2594
|
+
const rest = L - s - body;
|
|
2595
|
+
if (s < 0 || rest < 0) return null;
|
|
2596
|
+
const ids = new Set(pieces.map((p) => p.id));
|
|
2597
|
+
let n = 1;
|
|
2598
|
+
while (ids.has(`${host.id}b${n}`)) n += 1;
|
|
2599
|
+
const tail = {
|
|
2600
|
+
...host,
|
|
2601
|
+
id: `${host.id}b${n}`,
|
|
2602
|
+
x: exit.x,
|
|
2603
|
+
y: exit.y,
|
|
2604
|
+
rotationDeg: exit.headingDeg,
|
|
2605
|
+
lengthInches: rest
|
|
2606
|
+
};
|
|
2607
|
+
const out = pieces.map((p) => p.id === host.id ? { ...p, lengthInches: s } : p);
|
|
2608
|
+
const kept = out.filter((p) => p.id !== host.id || s > 0);
|
|
2609
|
+
return {
|
|
2610
|
+
pieces: [...kept, placed, ...rest > 0 ? [tail] : []],
|
|
2611
|
+
hostId: host.id,
|
|
2612
|
+
insertedId: placed.id
|
|
2613
|
+
};
|
|
2614
|
+
}
|
|
2615
|
+
function placeLocal(piece, x, y) {
|
|
2616
|
+
const rad = piece.rotationDeg * Math.PI / 180;
|
|
2617
|
+
const ly = piece.flipped ? -y : y;
|
|
2618
|
+
return {
|
|
2619
|
+
x: piece.x + x * Math.cos(rad) - ly * Math.sin(rad),
|
|
2620
|
+
y: piece.y + x * Math.sin(rad) + ly * Math.cos(rad)
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2623
|
+
function distanceToSegment(p, a, b) {
|
|
2624
|
+
const vx = b.x - a.x;
|
|
2625
|
+
const vy = b.y - a.y;
|
|
2626
|
+
const len2 = vx * vx + vy * vy;
|
|
2627
|
+
if (len2 === 0) return Math.hypot(p.x - a.x, p.y - a.y);
|
|
2628
|
+
const t = Math.max(0, Math.min(1, ((p.x - a.x) * vx + (p.y - a.y) * vy) / len2));
|
|
2629
|
+
return Math.hypot(p.x - (a.x + t * vx), p.y - (a.y + t * vy));
|
|
2630
|
+
}
|
|
2544
2631
|
var danglingDivergeWarning = (id) => `the route diverging at ${id} is not connected to anything`;
|
|
2545
2632
|
var unreachedWarning = (id) => `${id} is not reachable from the endplate \u2014 nothing connects it`;
|
|
2546
2633
|
function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS) {
|
|
@@ -3551,6 +3638,6 @@ function poseOverridesFromDoc(doc) {
|
|
|
3551
3638
|
return out;
|
|
3552
3639
|
}
|
|
3553
3640
|
|
|
3554
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, GENERIC_END_OF_TRACK, JOINT_SNAP_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, PINCH_EASE_INCHES, RAIL_GAUGE_INCHES, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
|
|
3641
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, GENERIC_END_OF_TRACK, JOINT_SNAP_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, PINCH_EASE_INCHES, RAIL_GAUGE_INCHES, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
|
|
3555
3642
|
//# sourceMappingURL=index.js.map
|
|
3556
3643
|
//# sourceMappingURL=index.js.map
|