@ifc-lite/create 2.9.2 → 3.1.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/ifc-creator-alignment-referents.d.ts +35 -0
- package/dist/ifc-creator-alignment-referents.d.ts.map +1 -0
- package/dist/ifc-creator-alignment-referents.js +89 -0
- package/dist/ifc-creator-alignment-referents.js.map +1 -0
- package/dist/ifc-creator-alignment-vertical.d.ts +40 -0
- package/dist/ifc-creator-alignment-vertical.d.ts.map +1 -0
- package/dist/ifc-creator-alignment-vertical.js +182 -0
- package/dist/ifc-creator-alignment-vertical.js.map +1 -0
- package/dist/ifc-creator-alignment.d.ts +15 -0
- package/dist/ifc-creator-alignment.d.ts.map +1 -1
- package/dist/ifc-creator-alignment.js +27 -28
- package/dist/ifc-creator-alignment.js.map +1 -1
- package/dist/ifc-creator-math.d.ts +22 -0
- package/dist/ifc-creator-math.d.ts.map +1 -1
- package/dist/ifc-creator-math.js +68 -2
- package/dist/ifc-creator-math.js.map +1 -1
- package/dist/ifc-creator.d.ts.map +1 -1
- package/dist/ifc-creator.js +3 -7
- package/dist/ifc-creator.js.map +1 -1
- package/dist/in-store/_emit-helpers.d.ts +2 -1
- package/dist/in-store/_emit-helpers.d.ts.map +1 -1
- package/dist/in-store/_emit-helpers.js +7 -7
- package/dist/in-store/_emit-helpers.js.map +1 -1
- package/dist/in-store/extract-walls.d.ts.map +1 -1
- package/dist/in-store/extract-walls.js +9 -1
- package/dist/in-store/extract-walls.js.map +1 -1
- package/dist/in-store/spatial-zone.d.ts.map +1 -1
- package/dist/in-store/spatial-zone.js +5 -5
- package/dist/in-store/spatial-zone.js.map +1 -1
- package/dist/in-store/wall.d.ts.map +1 -1
- package/dist/in-store/wall.js +4 -14
- package/dist/in-store/wall.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/landxml/landxml-to-ifc.d.ts +1 -1
- package/dist/landxml/landxml-to-ifc.d.ts.map +1 -1
- package/dist/landxml/landxml-to-ifc.js +9 -3
- package/dist/landxml/landxml-to-ifc.js.map +1 -1
- package/dist/landxml/profile-geometry.d.ts +50 -0
- package/dist/landxml/profile-geometry.d.ts.map +1 -0
- package/dist/landxml/profile-geometry.js +221 -0
- package/dist/landxml/profile-geometry.js.map +1 -0
- package/dist/landxml/profile-mapping.d.ts +36 -0
- package/dist/landxml/profile-mapping.d.ts.map +1 -0
- package/dist/landxml/profile-mapping.js +181 -0
- package/dist/landxml/profile-mapping.js.map +1 -0
- package/dist/landxml/profile-record.d.ts +46 -0
- package/dist/landxml/profile-record.d.ts.map +1 -0
- package/dist/landxml/profile-record.js +38 -0
- package/dist/landxml/profile-record.js.map +1 -0
- package/dist/landxml/refusals.d.ts +5 -1
- package/dist/landxml/refusals.d.ts.map +1 -1
- package/dist/landxml/refusals.js +29 -6
- package/dist/landxml/refusals.js.map +1 -1
- package/dist/landxml/result-types.d.ts +5 -0
- package/dist/landxml/result-types.d.ts.map +1 -1
- package/dist/landxml/station-equations.d.ts +69 -0
- package/dist/landxml/station-equations.d.ts.map +1 -0
- package/dist/landxml/station-equations.js +140 -0
- package/dist/landxml/station-equations.js.map +1 -0
- package/dist/landxml/writers.d.ts +3 -1
- package/dist/landxml/writers.d.ts.map +1 -1
- package/dist/landxml/writers.js +18 -1
- package/dist/landxml/writers.js.map +1 -1
- package/dist/types.d.ts +13 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* A LandXML design profile → `IfcAlignmentVerticalSegment` parameters
|
|
6
|
+
* (mapping spec §12.3–§12.5). Pure numbers: metres of distance along and of
|
|
7
|
+
* height, gradients as rise/run.
|
|
8
|
+
*
|
|
9
|
+
* The profile is authored as PVIs — tangent intersections — with a vertical
|
|
10
|
+
* curve at some of them. IFC wants the segments BETWEEN: grades, and the curves
|
|
11
|
+
* that round the PVIs off. This module turns the one into the other and then
|
|
12
|
+
* checks that the result passes through every authored point it should
|
|
13
|
+
* (§12.5), which is where a sign or a half-length error shows.
|
|
14
|
+
*/
|
|
15
|
+
import { ALIGNMENT_POSITION_TOLERANCE_M } from './alignment-mapping.js';
|
|
16
|
+
export class ProfileRefusal extends Error {
|
|
17
|
+
}
|
|
18
|
+
export function refuseProfile(message) {
|
|
19
|
+
throw new ProfileRefusal(message);
|
|
20
|
+
}
|
|
21
|
+
/** A grade or curve joins its neighbours to well under this; floating noise only. */
|
|
22
|
+
const JOIN_EPSILON_M = 1e-6;
|
|
23
|
+
/**
|
|
24
|
+
* Height and gradient `x` metres into a segment (0 ≤ x ≤ horizontalLength).
|
|
25
|
+
* The circle is evaluated from its centre, which sits `R` to the left of the
|
|
26
|
+
* start tangent for a sag and to the right for a crest.
|
|
27
|
+
*/
|
|
28
|
+
export function evaluateVertical(segment, x) {
|
|
29
|
+
const { startHeight: h0, startGradient: g0, endGradient: g1, horizontalLength: L } = segment;
|
|
30
|
+
if (segment.type === 'CONSTANTGRADIENT' || L === 0)
|
|
31
|
+
return { height: h0 + g0 * x, gradient: g0 };
|
|
32
|
+
if (segment.type === 'PARABOLICARC') {
|
|
33
|
+
return { height: h0 + g0 * x + ((g1 - g0) * x * x) / (2 * L), gradient: g0 + ((g1 - g0) * x) / L };
|
|
34
|
+
}
|
|
35
|
+
const radius = Math.abs(segment.radiusOfCurvature ?? 0);
|
|
36
|
+
const sag = g1 > g0;
|
|
37
|
+
const theta = Math.atan(g0);
|
|
38
|
+
const side = sag ? 1 : -1;
|
|
39
|
+
const cx = -side * radius * Math.sin(theta);
|
|
40
|
+
const cy = side * radius * Math.cos(theta);
|
|
41
|
+
const dx = x - cx;
|
|
42
|
+
const root = Math.sqrt(Math.max(0, radius * radius - dx * dx));
|
|
43
|
+
return { height: h0 + cy - side * root, gradient: side * dx / root };
|
|
44
|
+
}
|
|
45
|
+
/** Height of the whole profile at a distance along, or `null` outside it. */
|
|
46
|
+
export function profileHeightAt(segments, distAlong) {
|
|
47
|
+
for (const segment of segments) {
|
|
48
|
+
const x = distAlong - segment.startDistAlong;
|
|
49
|
+
if (x >= -JOIN_EPSILON_M && x <= segment.horizontalLength + JOIN_EPSILON_M) {
|
|
50
|
+
return evaluateVertical(segment, Math.min(Math.max(x, 0), segment.horizontalLength)).height;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
function positive(value, scale, what) {
|
|
56
|
+
if (value === null || !Number.isFinite(value) || value <= 0)
|
|
57
|
+
refuseProfile(`${what} is missing or not positive`);
|
|
58
|
+
return value * scale;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A grade change at or below this is no change: two grades computed from PVIs
|
|
62
|
+
* on one straight line differ by rounding (3.5e-17 for 0.001, #5930 review),
|
|
63
|
+
* and a "curve" between them has no representable curvature.
|
|
64
|
+
*/
|
|
65
|
+
const GRADE_EPSILON = 1e-9;
|
|
66
|
+
/**
|
|
67
|
+
* The segments that round off one PVI, in order — none for an equal-grade
|
|
68
|
+
* parabola, whose curve is the grade itself (§12.4).
|
|
69
|
+
*/
|
|
70
|
+
export function curveSegments(curve, pvi, gradeIn, gradeOut, units, label) {
|
|
71
|
+
const scale = units.linearScaleToMeters;
|
|
72
|
+
const rawDelta = gradeOut - gradeIn;
|
|
73
|
+
const delta = Math.abs(rawDelta) <= GRADE_EPSILON ? 0 : rawDelta;
|
|
74
|
+
const { distAlong: d, height: h } = pvi;
|
|
75
|
+
switch (curve.kind) {
|
|
76
|
+
case 'parabolic': {
|
|
77
|
+
const L = positive(curve.length, scale, `${label}'s length`);
|
|
78
|
+
if (delta === 0)
|
|
79
|
+
return [];
|
|
80
|
+
return [{
|
|
81
|
+
sourceId: curve.sourceId, type: 'PARABOLICARC', startDistAlong: d - L / 2, horizontalLength: L,
|
|
82
|
+
startHeight: h - (gradeIn * L) / 2, startGradient: gradeIn, endGradient: gradeOut, radiusOfCurvature: L / delta,
|
|
83
|
+
}];
|
|
84
|
+
}
|
|
85
|
+
case 'unsymmetrical_parabolic': {
|
|
86
|
+
const lengthIn = positive(curve.lengthIn, scale, `${label}'s lengthIn`);
|
|
87
|
+
const lengthOut = positive(curve.lengthOut, scale, `${label}'s lengthOut`);
|
|
88
|
+
if (delta === 0)
|
|
89
|
+
return [];
|
|
90
|
+
// Two parabolas sharing height and gradient at the PVI station (§12.3).
|
|
91
|
+
const middle = gradeIn + (delta * lengthOut) / (lengthIn + lengthOut);
|
|
92
|
+
const startHeight = h - gradeIn * lengthIn;
|
|
93
|
+
return [
|
|
94
|
+
{
|
|
95
|
+
sourceId: `${curve.sourceId}:in`, type: 'PARABOLICARC', startDistAlong: d - lengthIn,
|
|
96
|
+
horizontalLength: lengthIn, startHeight, startGradient: gradeIn, endGradient: middle,
|
|
97
|
+
radiusOfCurvature: lengthIn / (middle - gradeIn),
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
sourceId: `${curve.sourceId}:out`, type: 'PARABOLICARC', startDistAlong: d, horizontalLength: lengthOut,
|
|
101
|
+
startHeight: startHeight + ((gradeIn + middle) / 2) * lengthIn, startGradient: middle,
|
|
102
|
+
endGradient: gradeOut, radiusOfCurvature: lengthOut / (gradeOut - middle),
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
case 'circular': {
|
|
107
|
+
if (units.linearScaleToMeters !== units.elevationScaleToMeters) {
|
|
108
|
+
refuseProfile(`${label} is a circular curve in a file whose elevation unit differs from its linear unit, so its radius has no single unit`);
|
|
109
|
+
}
|
|
110
|
+
if (delta === 0)
|
|
111
|
+
refuseProfile(`${label} is a circular curve between two equal grades`);
|
|
112
|
+
// Some producers sign the radius, negative for a crest (§12.4). A sign
|
|
113
|
+
// that contradicts the grades is refused rather than trusted either way.
|
|
114
|
+
if (curve.radius !== null && curve.radius < 0 && delta > 0) {
|
|
115
|
+
refuseProfile(`${label} declares a negative (crest) radius, but its grades make a sag`);
|
|
116
|
+
}
|
|
117
|
+
const radius = positive(curve.radius === null ? null : Math.abs(curve.radius), scale, `${label}'s radius`);
|
|
118
|
+
const t1 = Math.atan(gradeIn);
|
|
119
|
+
const t2 = Math.atan(gradeOut);
|
|
120
|
+
const tangent = radius * Math.tan(Math.abs(t2 - t1) / 2);
|
|
121
|
+
const horizontal = radius * Math.abs(Math.sin(t2) - Math.sin(t1));
|
|
122
|
+
const arc = radius * Math.abs(t2 - t1);
|
|
123
|
+
// Radius and grades fix the curve; the declared length only confirms
|
|
124
|
+
// them. Producers differ on which length they mean (§12.4), so either
|
|
125
|
+
// agreeing is agreement, and neither is a contradiction.
|
|
126
|
+
const declared = positive(curve.length, scale, `${label}'s length`);
|
|
127
|
+
if (Math.min(Math.abs(declared - horizontal), Math.abs(declared - arc)) > ALIGNMENT_POSITION_TOLERANCE_M) {
|
|
128
|
+
refuseProfile(`${label} declares a length of ${declared.toFixed(3)} m, but its radius and grades give an arc length of `
|
|
129
|
+
+ `${arc.toFixed(3)} m (horizontal length ${horizontal.toFixed(3)} m)`);
|
|
130
|
+
}
|
|
131
|
+
return [{
|
|
132
|
+
sourceId: curve.sourceId, type: 'CIRCULARARC', startDistAlong: d - tangent * Math.cos(t1),
|
|
133
|
+
horizontalLength: horizontal, startHeight: h - tangent * Math.sin(t1), startGradient: gradeIn,
|
|
134
|
+
endGradient: gradeOut, radiusOfCurvature: Math.sign(delta) * radius,
|
|
135
|
+
}];
|
|
136
|
+
}
|
|
137
|
+
default:
|
|
138
|
+
return refuseProfile(`${label} has an unrecognised vertical curve type`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function grade(sourceId, from, to, a, b) {
|
|
142
|
+
const g = (b.height - a.height) / (b.distAlong - a.distAlong);
|
|
143
|
+
return {
|
|
144
|
+
sourceId, type: 'CONSTANTGRADIENT', startDistAlong: from, horizontalLength: to - from,
|
|
145
|
+
startHeight: a.height + g * (from - a.distAlong), startGradient: g, endGradient: g, radiusOfCurvature: null,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Assemble grades and curves between the PVIs. `curves[i]` holds the
|
|
150
|
+
* segments rounding off PVI `i` (empty for a bare grade break).
|
|
151
|
+
*/
|
|
152
|
+
export function assembleProfile(profileSourceId, vertices, curves) {
|
|
153
|
+
const segments = [];
|
|
154
|
+
let cursor = vertices[0].distAlong;
|
|
155
|
+
const addGrade = (to, leg) => {
|
|
156
|
+
const length = to - cursor;
|
|
157
|
+
if (length < -JOIN_EPSILON_M) {
|
|
158
|
+
refuseProfile(`the vertical curve at PVI ${leg + 1} starts ${(-length).toFixed(3)} m before the previous one ends`);
|
|
159
|
+
}
|
|
160
|
+
if (length > JOIN_EPSILON_M) {
|
|
161
|
+
segments.push(grade(`${profileSourceId}:grade:${segments.length}`, cursor, to, vertices[leg - 1], vertices[leg]));
|
|
162
|
+
}
|
|
163
|
+
cursor = Math.max(cursor, to);
|
|
164
|
+
};
|
|
165
|
+
for (let index = 1; index < vertices.length; index += 1) {
|
|
166
|
+
const pieces = curves[index] ?? [];
|
|
167
|
+
if (pieces.length === 0) {
|
|
168
|
+
addGrade(vertices[index].distAlong, index);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
addGrade(pieces[0].startDistAlong, index);
|
|
172
|
+
const last = pieces[pieces.length - 1];
|
|
173
|
+
const end = last.startDistAlong + last.horizontalLength;
|
|
174
|
+
if (end > vertices[index + 1].distAlong + JOIN_EPSILON_M) {
|
|
175
|
+
refuseProfile(`the vertical curve at PVI ${index + 1} ends ${(end - vertices[index + 1].distAlong).toFixed(3)} m past PVI ${index + 2}`);
|
|
176
|
+
}
|
|
177
|
+
// A join closer than the epsilon is the same point: snap the curve onto
|
|
178
|
+
// the cursor so no sub-micrometre gap reaches the written curve.
|
|
179
|
+
if (Math.abs(pieces[0].startDistAlong - cursor) <= JOIN_EPSILON_M)
|
|
180
|
+
pieces[0].startDistAlong = cursor;
|
|
181
|
+
segments.push(...pieces);
|
|
182
|
+
cursor = end;
|
|
183
|
+
}
|
|
184
|
+
return segments;
|
|
185
|
+
}
|
|
186
|
+
/** §12.5: joins are continuous, and the profile passes through what it must. */
|
|
187
|
+
export function checkProfile(segments, vertices, curves) {
|
|
188
|
+
const tolerance = ALIGNMENT_POSITION_TOLERANCE_M;
|
|
189
|
+
segments.slice(1).forEach((next, index) => {
|
|
190
|
+
const previous = segments[index];
|
|
191
|
+
const end = evaluateVertical(previous, previous.horizontalLength);
|
|
192
|
+
const heightGap = Math.abs(end.height - next.startHeight);
|
|
193
|
+
const gradeGap = Math.abs(end.gradient - next.startGradient);
|
|
194
|
+
const distGap = Math.abs(previous.startDistAlong + previous.horizontalLength - next.startDistAlong);
|
|
195
|
+
// Only a bare grade break (two grades meeting at a PVI) may change gradient.
|
|
196
|
+
const gradeBreak = previous.type === 'CONSTANTGRADIENT' && next.type === 'CONSTANTGRADIENT';
|
|
197
|
+
if (distGap > tolerance || heightGap > tolerance || (gradeGap > 1e-6 && !gradeBreak)) {
|
|
198
|
+
refuseProfile(`vertical segment ${index + 2} does not continue segment ${index + 1} (height gap ${heightGap.toFixed(4)} m)`);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
vertices.forEach((vertex, index) => {
|
|
202
|
+
const pieces = curves[index] ?? [];
|
|
203
|
+
if (pieces.length === 0) {
|
|
204
|
+
const height = profileHeightAt(segments, vertex.distAlong);
|
|
205
|
+
if (height === null || Math.abs(height - vertex.height) > tolerance) {
|
|
206
|
+
refuseProfile(`the profile misses PVI ${index + 1} (${height === null ? 'not reached' : `${Math.abs(height - vertex.height).toFixed(4)} m`})`);
|
|
207
|
+
}
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
// A curve's PVI is a tangent intersection: both tangents, extended, meet it.
|
|
211
|
+
const first = pieces[0];
|
|
212
|
+
const last = pieces[pieces.length - 1];
|
|
213
|
+
const lastEnd = evaluateVertical(last, last.horizontalLength);
|
|
214
|
+
const back = first.startHeight + first.startGradient * (vertex.distAlong - first.startDistAlong);
|
|
215
|
+
const ahead = lastEnd.height - last.endGradient * (last.startDistAlong + last.horizontalLength - vertex.distAlong);
|
|
216
|
+
if (Math.abs(back - vertex.height) > tolerance || Math.abs(ahead - vertex.height) > tolerance) {
|
|
217
|
+
refuseProfile(`the tangents of the vertical curve at PVI ${index + 1} do not meet at its authored point`);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=profile-geometry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-geometry.js","sourceRoot":"","sources":["../../src/landxml/profile-geometry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which LandXML profiles become an `IfcAlignmentVertical`, and which are
|
|
3
|
+
* refused by name (mapping spec §12.2).
|
|
4
|
+
*
|
|
5
|
+
* Like `alignment-mapping.ts`, no STEP is written here, so the export dialog's
|
|
6
|
+
* pre-flight and the export itself give the same answer. The geometry lives in
|
|
7
|
+
* `profile-geometry.ts`; this module decides linkage and runs the mapping.
|
|
8
|
+
*/
|
|
9
|
+
import { type AlignmentMapping } from './alignment-mapping.js';
|
|
10
|
+
import { type VerticalSegment } from './profile-geometry.js';
|
|
11
|
+
import type { LandXmlIfcUnits } from './source-types.js';
|
|
12
|
+
import { type StationEquationMapping } from './station-equations.js';
|
|
13
|
+
/** A design profile mapped onto a written alignment. */
|
|
14
|
+
export interface MappedProfile {
|
|
15
|
+
sourceId: string;
|
|
16
|
+
name: string;
|
|
17
|
+
alignmentSourceId: string;
|
|
18
|
+
segments: VerticalSegment[];
|
|
19
|
+
}
|
|
20
|
+
export interface RefusedProfile {
|
|
21
|
+
sourceId: string;
|
|
22
|
+
name: string;
|
|
23
|
+
reason: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ProfileMapping {
|
|
26
|
+
mapped: MappedProfile[];
|
|
27
|
+
refused: RefusedProfile[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Map every profile onto the alignments `alignmentMapping` writes, and refuse
|
|
31
|
+
* the rest by name (§12.2). `alignments` is the source's raw list — a
|
|
32
|
+
* profile's link is checked against it, not only against the written ones, so
|
|
33
|
+
* a profile of a refused alignment says so rather than reading as unlinked.
|
|
34
|
+
*/
|
|
35
|
+
export declare function mapProfiles(profiles: readonly unknown[] | undefined, alignments: readonly unknown[] | undefined, alignmentMapping: AlignmentMapping, units: LandXmlIfcUnits | null, stationing?: ReadonlyMap<string, StationEquationMapping>): ProfileMapping;
|
|
36
|
+
//# sourceMappingURL=profile-mapping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-mapping.d.ts","sourceRoot":"","sources":["../../src/landxml/profile-mapping.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,EAAqD,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClH,OAAO,EAC4F,KAAK,eAAe,EACtH,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAuB,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAuB,KAAK,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAK1F,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAmDD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,EAAE,UAAU,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,EACpF,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,EACjE,UAAU,GAAE,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAa,GAClE,cAAc,CAkFhB"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* Which LandXML profiles become an `IfcAlignmentVertical`, and which are
|
|
6
|
+
* refused by name (mapping spec §12.2).
|
|
7
|
+
*
|
|
8
|
+
* Like `alignment-mapping.ts`, no STEP is written here, so the export dialog's
|
|
9
|
+
* pre-flight and the export itself give the same answer. The geometry lives in
|
|
10
|
+
* `profile-geometry.ts`; this module decides linkage and runs the mapping.
|
|
11
|
+
*/
|
|
12
|
+
import { ALIGNMENT_POSITION_TOLERANCE_M, isAlignmentRecord } from './alignment-mapping.js';
|
|
13
|
+
import { ProfileRefusal, assembleProfile, checkProfile, curveSegments, refuseProfile, } from './profile-geometry.js';
|
|
14
|
+
import { profileRecordProblem } from './profile-record.js';
|
|
15
|
+
import { distancesForStation } from './station-equations.js';
|
|
16
|
+
function mapDesignProfile(profile, distanceOf, horizontalLength, units) {
|
|
17
|
+
if (profile.pvis.length < 2)
|
|
18
|
+
refuseProfile('it has fewer than two PVIs, so it has no grade');
|
|
19
|
+
const vertices = profile.pvis.map((pvi, index) => {
|
|
20
|
+
if (pvi.elevation === null || !Number.isFinite(pvi.elevation) || !Number.isFinite(pvi.station)) {
|
|
21
|
+
refuseProfile(`its PVI ${index + 1} has no finite station and elevation`);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
sourceId: pvi.sourceId,
|
|
25
|
+
distAlong: distanceOf(pvi.station, `its PVI ${index + 1}`),
|
|
26
|
+
height: pvi.elevation * units.elevationScaleToMeters,
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
vertices.slice(1).forEach((vertex, index) => {
|
|
30
|
+
if (vertex.distAlong <= vertices[index].distAlong)
|
|
31
|
+
refuseProfile(`its PVI ${index + 2} does not advance in station`);
|
|
32
|
+
});
|
|
33
|
+
const start = vertices[0].distAlong;
|
|
34
|
+
const end = vertices[vertices.length - 1].distAlong;
|
|
35
|
+
if (start < -ALIGNMENT_POSITION_TOLERANCE_M || end > horizontalLength + ALIGNMENT_POSITION_TOLERANCE_M) {
|
|
36
|
+
refuseProfile(`it runs from ${start.toFixed(3)} m to ${end.toFixed(3)} m along an alignment ${horizontalLength.toFixed(3)} m long`);
|
|
37
|
+
}
|
|
38
|
+
const gradeOf = (a, b) => (b.height - a.height) / (b.distAlong - a.distAlong);
|
|
39
|
+
const curves = vertices.map(() => []);
|
|
40
|
+
const seen = new Set();
|
|
41
|
+
profile.verticalCurves.forEach((curve, curveIndex) => {
|
|
42
|
+
const label = `vertical curve ${curveIndex + 1}`;
|
|
43
|
+
// The parser records a curve's PVI in `pvis` with the same station and
|
|
44
|
+
// elevation — the same pairing `rust/landxml`'s profile evaluator uses.
|
|
45
|
+
const index = profile.pvis.findIndex((pvi) => pvi.station === curve.station && pvi.elevation === curve.elevation);
|
|
46
|
+
if (index <= 0 || index >= vertices.length - 1) {
|
|
47
|
+
refuseProfile(`${label} is not at an interior PVI, so it has no grade on both sides`);
|
|
48
|
+
}
|
|
49
|
+
if (seen.has(index))
|
|
50
|
+
refuseProfile(`PVI ${index + 1} carries more than one vertical curve`);
|
|
51
|
+
seen.add(index);
|
|
52
|
+
const before = vertices[index - 1];
|
|
53
|
+
const pvi = vertices[index];
|
|
54
|
+
const after = vertices[index + 1];
|
|
55
|
+
curves[index] = curveSegments(curve, pvi, gradeOf(before, pvi), gradeOf(pvi, after), units, label);
|
|
56
|
+
});
|
|
57
|
+
const segments = assembleProfile(profile.sourceId, vertices, curves);
|
|
58
|
+
checkProfile(segments, vertices, curves);
|
|
59
|
+
return segments;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Map every profile onto the alignments `alignmentMapping` writes, and refuse
|
|
63
|
+
* the rest by name (§12.2). `alignments` is the source's raw list — a
|
|
64
|
+
* profile's link is checked against it, not only against the written ones, so
|
|
65
|
+
* a profile of a refused alignment says so rather than reading as unlinked.
|
|
66
|
+
*/
|
|
67
|
+
export function mapProfiles(profiles, alignments, alignmentMapping, units, stationing = new Map()) {
|
|
68
|
+
const result = { mapped: [], refused: [] };
|
|
69
|
+
const records = (alignments ?? []).filter(isAlignmentRecord);
|
|
70
|
+
const written = new Map(alignmentMapping.mapped.map((alignment) => [alignment.sourceId, alignment]));
|
|
71
|
+
const designCount = new Map();
|
|
72
|
+
const valid = [];
|
|
73
|
+
(profiles ?? []).forEach((candidate, index) => {
|
|
74
|
+
const problem = profileRecordProblem(candidate);
|
|
75
|
+
if (problem === null) {
|
|
76
|
+
valid.push(candidate);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const header = candidate;
|
|
80
|
+
const named = typeof header?.sourceId === 'string' && typeof header.name === 'string';
|
|
81
|
+
result.refused.push({
|
|
82
|
+
sourceId: named ? header.sourceId : `profile[${index}]`,
|
|
83
|
+
name: named ? header.name || header.sourceId : `profile ${index + 1}`,
|
|
84
|
+
reason: problem,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
// A profile is linked when its alignment exists and, if that alignment
|
|
88
|
+
// lists its profiles, lists this one. Only LINKED design profiles compete
|
|
89
|
+
// for the alignment's one vertical layout: an unlinked sibling is refused
|
|
90
|
+
// on its own and must not make the linked one look ambiguous (#5930 review).
|
|
91
|
+
const alignmentOf = (profile) => records.find((record) => record.sourceId === profile.parentAlignmentSourceId);
|
|
92
|
+
const isLinked = (profile) => {
|
|
93
|
+
const alignment = alignmentOf(profile);
|
|
94
|
+
const listed = alignment?.profileSourceIds ?? [];
|
|
95
|
+
return alignment !== undefined && (listed.length === 0 || listed.includes(profile.sourceId));
|
|
96
|
+
};
|
|
97
|
+
for (const profile of valid) {
|
|
98
|
+
if (profile.kind === 'design' && isLinked(profile)) {
|
|
99
|
+
designCount.set(profile.parentAlignmentSourceId, (designCount.get(profile.parentAlignmentSourceId) ?? 0) + 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const profile of valid) {
|
|
103
|
+
const refuse = (reason) => {
|
|
104
|
+
result.refused.push({ sourceId: profile.sourceId, name: profile.name || profile.sourceId, reason });
|
|
105
|
+
};
|
|
106
|
+
const alignment = alignmentOf(profile);
|
|
107
|
+
// An empty `profileSourceIds` declares nothing; a non-empty one must agree.
|
|
108
|
+
if (!alignment || !isLinked(profile)) {
|
|
109
|
+
refuse('it is not linked to any alignment in the file');
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const alignmentName = alignment.name || alignment.sourceId;
|
|
113
|
+
const mapped = written.get(alignment.sourceId);
|
|
114
|
+
if (!mapped || units === null) {
|
|
115
|
+
refuse(`its alignment '${alignmentName}' is not written, so there is no horizontal to measure it along`);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (profile.kind === 'sampled') {
|
|
119
|
+
refuse('it is a sampled ground profile (ProfSurf), not a design vertical layout');
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const designs = designCount.get(alignment.sourceId) ?? 0;
|
|
123
|
+
if (designs > 1) {
|
|
124
|
+
refuse(`its alignment '${alignmentName}' has ${designs} design profiles, and IFC nests one vertical layout under an alignment; choosing one would be a guess`);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const horizontalLength = mapped.segments.reduce((total, segment) => total + segment.length, 0);
|
|
128
|
+
const distanceOf = profileDistances(alignment, mapped.startStation, horizontalLength, units, stationing);
|
|
129
|
+
if (typeof distanceOf === 'string') {
|
|
130
|
+
refuse(distanceOf);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
result.mapped.push({
|
|
135
|
+
sourceId: profile.sourceId,
|
|
136
|
+
name: profile.name,
|
|
137
|
+
alignmentSourceId: alignment.sourceId,
|
|
138
|
+
segments: mapDesignProfile(profile, distanceOf, horizontalLength, units),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (!(error instanceof ProfileRefusal))
|
|
143
|
+
throw error;
|
|
144
|
+
refuse(error.message);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* How a profile's stations become distances along its alignment (§14.5).
|
|
151
|
+
*
|
|
152
|
+
* Without station equations, linearly from the start station. With written
|
|
153
|
+
* ones, through the displayed stationing they define: a PVI station must occur
|
|
154
|
+
* at exactly one place along the alignment, and one in a forward jump's gap or
|
|
155
|
+
* displayed twice after a backward jump is refused by name, never guessed. When
|
|
156
|
+
* the alignment's equations were themselves refused (§14.2) there is no
|
|
157
|
+
* stationing to read the profile against, so it is refused as a whole.
|
|
158
|
+
*/
|
|
159
|
+
function profileDistances(alignment, startStation, length, units, stationing) {
|
|
160
|
+
const scale = units.linearScaleToMeters;
|
|
161
|
+
if ((alignment.stationEquations?.length ?? 0) === 0) {
|
|
162
|
+
return (station) => station * scale - startStation;
|
|
163
|
+
}
|
|
164
|
+
const alignmentName = alignment.name || alignment.sourceId;
|
|
165
|
+
const mapping = stationing.get(alignment.sourceId);
|
|
166
|
+
if (!mapping || mapping.refusal !== null) {
|
|
167
|
+
return `its alignment '${alignmentName}' has station equations that are not written, so its stations cannot be placed along it`;
|
|
168
|
+
}
|
|
169
|
+
return (station, label) => {
|
|
170
|
+
const places = distancesForStation(station * scale, startStation, mapping.equations, length);
|
|
171
|
+
if (places.length === 0) {
|
|
172
|
+
refuseProfile(`${label} is at station ${station}, which falls in a station-equation gap of '${alignmentName}'`);
|
|
173
|
+
}
|
|
174
|
+
if (places.length > 1) {
|
|
175
|
+
refuseProfile(`${label} is at station ${station}, which '${alignmentName}' displays at ${places.length} places `
|
|
176
|
+
+ `(${places.map((place) => `${place.toFixed(3)} m`).join(', ')}); choosing one would be a guess`);
|
|
177
|
+
}
|
|
178
|
+
return places[0];
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=profile-mapping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-mapping.js","sourceRoot":"","sources":["../../src/landxml/profile-mapping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shape of one `LandXmlIfcSource.profiles` record, and its run-time check
|
|
3
|
+
* (mapping spec §12).
|
|
4
|
+
*
|
|
5
|
+
* `profiles` stays `unknown[]` on the source (narrowing a published input type
|
|
6
|
+
* is a breaking change, #5370 review), so every record is checked here before
|
|
7
|
+
* the mapper reads it — exactly as `alignment-record.ts` does for alignments.
|
|
8
|
+
* A record that fails is refused by name, never read into.
|
|
9
|
+
*
|
|
10
|
+
* The shapes mirror the viewer's `LandXmlProfile` field for field, so the
|
|
11
|
+
* viewer's parsed document satisfies them without a translation layer.
|
|
12
|
+
*/
|
|
13
|
+
/** One `PVI` (or sampled station/elevation pair), in the file's declared units. */
|
|
14
|
+
export interface LandXmlIfcProfilePoint {
|
|
15
|
+
sourceId: string;
|
|
16
|
+
/** A STATION, not a distance along: `staStart` has not been subtracted. */
|
|
17
|
+
station: number;
|
|
18
|
+
elevation: number | null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A `ParaCurve`, `UnsymParaCurve` or `CircCurve`, anchored at its PVI. The
|
|
22
|
+
* parser also records that PVI in `pvis`, with the same station and elevation.
|
|
23
|
+
*/
|
|
24
|
+
export interface LandXmlIfcVerticalCurve {
|
|
25
|
+
sourceId: string;
|
|
26
|
+
kind: 'parabolic' | 'unsymmetrical_parabolic' | 'circular';
|
|
27
|
+
station: number;
|
|
28
|
+
elevation: number | null;
|
|
29
|
+
length: number | null;
|
|
30
|
+
lengthIn: number | null;
|
|
31
|
+
lengthOut: number | null;
|
|
32
|
+
radius: number | null;
|
|
33
|
+
}
|
|
34
|
+
/** A `ProfAlign` (`kind: 'design'`) or `ProfSurf` (`kind: 'sampled'`) under an alignment. */
|
|
35
|
+
export interface LandXmlIfcProfile {
|
|
36
|
+
sourceId: string;
|
|
37
|
+
parentAlignmentSourceId: string;
|
|
38
|
+
name: string;
|
|
39
|
+
kind: 'design' | 'sampled';
|
|
40
|
+
/** Authored order. */
|
|
41
|
+
pvis: readonly LandXmlIfcProfilePoint[];
|
|
42
|
+
verticalCurves: readonly LandXmlIfcVerticalCurve[];
|
|
43
|
+
}
|
|
44
|
+
/** Why this record is not a `LandXmlIfcProfile`, or `null` when it is. */
|
|
45
|
+
export declare function profileRecordProblem(value: unknown): string | null;
|
|
46
|
+
//# sourceMappingURL=profile-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-record.d.ts","sourceRoot":"","sources":["../../src/landxml/profile-record.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,WAAW,GAAG,yBAAyB,GAAG,UAAU,CAAC;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,6FAA6F;AAC7F,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB,EAAE,MAAM,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,sBAAsB;IACtB,IAAI,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACxC,cAAc,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACpD;AAqBD,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAgBlE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
const isObject = (value) => typeof value === 'object' && value !== null;
|
|
5
|
+
const isNumber = (value) => typeof value === 'number';
|
|
6
|
+
const isOptionalNumber = (value) => value === null || isNumber(value);
|
|
7
|
+
function isPoint(value) {
|
|
8
|
+
return isObject(value) && typeof value.sourceId === 'string' && isNumber(value.station)
|
|
9
|
+
&& isOptionalNumber(value.elevation);
|
|
10
|
+
}
|
|
11
|
+
function isCurve(value) {
|
|
12
|
+
return isObject(value) && typeof value.sourceId === 'string'
|
|
13
|
+
&& (value.kind === 'parabolic' || value.kind === 'unsymmetrical_parabolic' || value.kind === 'circular')
|
|
14
|
+
&& isNumber(value.station) && isOptionalNumber(value.elevation)
|
|
15
|
+
&& isOptionalNumber(value.length) && isOptionalNumber(value.lengthIn)
|
|
16
|
+
&& isOptionalNumber(value.lengthOut) && isOptionalNumber(value.radius);
|
|
17
|
+
}
|
|
18
|
+
/** Why this record is not a `LandXmlIfcProfile`, or `null` when it is. */
|
|
19
|
+
export function profileRecordProblem(value) {
|
|
20
|
+
if (!isObject(value)
|
|
21
|
+
|| typeof value.sourceId !== 'string'
|
|
22
|
+
|| typeof value.parentAlignmentSourceId !== 'string'
|
|
23
|
+
|| typeof value.name !== 'string'
|
|
24
|
+
|| (value.kind !== 'design' && value.kind !== 'sampled')
|
|
25
|
+
|| !Array.isArray(value.pvis)
|
|
26
|
+
|| !Array.isArray(value.verticalCurves)) {
|
|
27
|
+
return 'it is not a profile record (it needs a sourceId, a parentAlignmentSourceId, a name, a design or '
|
|
28
|
+
+ 'sampled kind, and PVI and vertical-curve lists)';
|
|
29
|
+
}
|
|
30
|
+
const badPoint = value.pvis.findIndex((point) => !isPoint(point));
|
|
31
|
+
if (badPoint !== -1)
|
|
32
|
+
return `its PVI ${badPoint + 1} is not a station/elevation record`;
|
|
33
|
+
const badCurve = value.verticalCurves.findIndex((curve) => !isCurve(curve));
|
|
34
|
+
if (badCurve !== -1)
|
|
35
|
+
return `its vertical curve ${badCurve + 1} is not a ParaCurve, UnsymParaCurve or CircCurve record`;
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=profile-record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-record.js","sourceRoot":"","sources":["../../src/landxml/profile-record.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAmD/D,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AAClG,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAW,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AACxE,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAW,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC;AAExF,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;WAClF,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;WACvD,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAyB,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC;WACrG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC;WAC5D,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC;WAClE,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC3E,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;WACf,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;WAClC,OAAO,KAAK,CAAC,uBAAuB,KAAK,QAAQ;WACjD,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;WAC9B,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;WACrD,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;WAC1B,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1C,OAAO,kGAAkG;cACrG,iDAAiD,CAAC;IACxD,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,IAAI,QAAQ,KAAK,CAAC,CAAC;QAAE,OAAO,WAAW,QAAQ,GAAG,CAAC,oCAAoC,CAAC;IACxF,MAAM,QAAQ,GAAG,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5E,IAAI,QAAQ,KAAK,CAAC,CAAC;QAAE,OAAO,sBAAsB,QAAQ,GAAG,CAAC,yDAAyD,CAAC;IACxH,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
import type { LandXmlIfcSource, LandXmlIfcSurface } from './source-types.js';
|
|
9
9
|
import type { LandXmlRefusal } from './result-types.js';
|
|
10
10
|
import { type AlignmentMapping, type RefusedAlignment } from './alignment-mapping.js';
|
|
11
|
+
import { type ProfileMapping, type RefusedProfile } from './profile-mapping.js';
|
|
12
|
+
import { type StationEquationMapping } from './station-equations.js';
|
|
11
13
|
/**
|
|
12
14
|
* A surface v1 can write: a rendered TIN with vertices and at least one
|
|
13
15
|
* VISIBLE face. A surface whose every face is an authored `<F i="true">` draws
|
|
@@ -24,12 +26,14 @@ export declare function isMappableSurface(surface: LandXmlIfcSurface): boolean;
|
|
|
24
26
|
*/
|
|
25
27
|
/** The alignment mapping for a source, computed the one way both the plan and the export use. */
|
|
26
28
|
export declare function alignmentMappingOf(source: LandXmlIfcSource): AlignmentMapping;
|
|
27
|
-
export declare function collectRefusals(source: LandXmlIfcSource, alignmentMapping?: AlignmentMapping): LandXmlRefusal[];
|
|
29
|
+
export declare function collectRefusals(source: LandXmlIfcSource, alignmentMapping?: AlignmentMapping, profileMapping?: ProfileMapping, stationing?: ReadonlyMap<string, StationEquationMapping>): LandXmlRefusal[];
|
|
28
30
|
/**
|
|
29
31
|
* Name each refused alignment and why. A count alone ("2 alignments") leaves
|
|
30
32
|
* the operator unable to tell a spiral type from a gap from a sign problem.
|
|
31
33
|
*/
|
|
32
34
|
export declare function alignmentRefusalMessage(refused: readonly RefusedAlignment[]): string;
|
|
35
|
+
/** Name each refused profile and why (§12.6), as alignments are. */
|
|
36
|
+
export declare function profileRefusalMessage(refused: readonly RefusedProfile[]): string;
|
|
33
37
|
/**
|
|
34
38
|
* The sentence shown when nothing in the source is mappable.
|
|
35
39
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refusals.d.ts","sourceRoot":"","sources":["../../src/landxml/refusals.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"refusals.d.ts","sourceRoot":"","sources":["../../src/landxml/refusals.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAuB,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAClG,OAAO,KAAK,EAAE,cAAc,EAAwB,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EACgD,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAClG,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EAAsB,KAAK,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAmCzF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAIrE;AAED;;;;;;GAMG;AACH,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAE7E;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,GAAE,gBAA6C,EACzF,cAAc,GAAE,cAEf,EACD,UAAU,GAAE,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAgD,GACrG,cAAc,EAAE,CA2ClB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,CAOpF;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAKhF;AAcD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAOzE"}
|