@ifc-lite/cli 0.21.1 → 0.23.1
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/commands/clash.d.ts.map +1 -1
- package/dist/commands/clash.js +88 -46
- package/dist/commands/clash.js.map +1 -1
- package/dist/commands/diagnose-geometry.d.ts.map +1 -1
- package/dist/commands/diagnose-geometry.js +28 -22
- package/dist/commands/diagnose-geometry.js.map +1 -1
- package/dist/commands/diff-content.d.ts +11 -0
- package/dist/commands/diff-content.d.ts.map +1 -0
- package/dist/commands/diff-content.js +270 -0
- package/dist/commands/diff-content.js.map +1 -0
- package/dist/commands/diff-engine.d.ts +23 -0
- package/dist/commands/diff-engine.d.ts.map +1 -0
- package/dist/commands/diff-engine.js +159 -0
- package/dist/commands/diff-engine.js.map +1 -0
- package/dist/commands/diff-scope.d.ts +77 -0
- package/dist/commands/diff-scope.d.ts.map +1 -0
- package/dist/commands/diff-scope.js +160 -0
- package/dist/commands/diff-scope.js.map +1 -0
- package/dist/commands/diff-test-helpers.d.ts +70 -0
- package/dist/commands/diff-test-helpers.d.ts.map +1 -0
- package/dist/commands/diff-test-helpers.js +203 -0
- package/dist/commands/diff-test-helpers.js.map +1 -0
- package/dist/commands/diff.d.ts +1 -0
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +71 -25
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/eval.d.ts.map +1 -1
- package/dist/commands/eval.js +7 -3
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +45 -16
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/extract-entities.d.ts.map +1 -1
- package/dist/commands/extract-entities.js +8 -2
- package/dist/commands/extract-entities.js.map +1 -1
- package/dist/commands/gym/channels.d.ts.map +1 -1
- package/dist/commands/gym/channels.js +4 -3
- package/dist/commands/gym/channels.js.map +1 -1
- package/dist/commands/gym.d.ts.map +1 -1
- package/dist/commands/gym.js +77 -62
- package/dist/commands/gym.js.map +1 -1
- package/dist/commands/layer-push.d.ts.map +1 -1
- package/dist/commands/layer-push.js +2 -0
- package/dist/commands/layer-push.js.map +1 -1
- package/dist/commands/query.d.ts +30 -0
- package/dist/commands/query.d.ts.map +1 -1
- package/dist/commands/query.js +32 -17
- package/dist/commands/query.js.map +1 -1
- package/dist/commands/schema.d.ts.map +1 -1
- package/dist/commands/schema.js +23 -2
- package/dist/commands/schema.js.map +1 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +36 -5
- package/dist/commands/validate.js.map +1 -1
- package/dist/hbjson-export.d.ts.map +1 -1
- package/dist/hbjson-export.js +27 -24
- package/dist/hbjson-export.js.map +1 -1
- package/dist/headless-backend.d.ts.map +1 -1
- package/dist/headless-backend.js +44 -4
- package/dist/headless-backend.js.map +1 -1
- package/dist/index.js +6 -13
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts +8 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +21 -0
- package/dist/output.js.map +1 -1
- package/dist/version.d.ts +14 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +38 -0
- package/dist/version.js.map +1 -0
- package/package.json +20 -19
|
@@ -0,0 +1,203 @@
|
|
|
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
|
+
/** Shared STEP fixtures for the `diff --by-content` test suites (issue #1891). */
|
|
5
|
+
/** A 22-character IFC GlobalId from a short mnemonic. */
|
|
6
|
+
export function guid(mnemonic) {
|
|
7
|
+
return (mnemonic + '0'.repeat(22)).slice(0, 22);
|
|
8
|
+
}
|
|
9
|
+
/** A minimal but real model: project, units, context, storey, two named walls
|
|
10
|
+
* with a spatial containment relation. `wallA`/`wallB` are the GlobalIds, so a
|
|
11
|
+
* "re-export" is the same call with different ones. */
|
|
12
|
+
export function model(wallA, wallB) {
|
|
13
|
+
return `ISO-10303-21;
|
|
14
|
+
HEADER;
|
|
15
|
+
FILE_DESCRIPTION((''),'2;1');
|
|
16
|
+
FILE_NAME('m','2026',(''),(''),'','','');
|
|
17
|
+
FILE_SCHEMA(('IFC4'));
|
|
18
|
+
ENDSEC;
|
|
19
|
+
DATA;
|
|
20
|
+
#1= IFCPROJECT('${guid('PROJ')}',$,'Proj',$,$,$,$,(#20),#30);
|
|
21
|
+
#20= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-5,#21,$);
|
|
22
|
+
#21= IFCAXIS2PLACEMENT3D(#22,$,$);
|
|
23
|
+
#22= IFCCARTESIANPOINT((0.,0.,0.));
|
|
24
|
+
#30= IFCUNITASSIGNMENT((#31));
|
|
25
|
+
#31= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
|
|
26
|
+
#40= IFCLOCALPLACEMENT($,#21);
|
|
27
|
+
#41= IFCBUILDINGSTOREY('${guid('STOR')}',$,'L01',$,$,#40,$,$,.ELEMENT.,0.);
|
|
28
|
+
#50= IFCLOCALPLACEMENT(#40,#21);
|
|
29
|
+
#60= IFCRECTANGLEPROFILEDEF(.AREA.,$,#21,2.,0.2);
|
|
30
|
+
#61= IFCEXTRUDEDAREASOLID(#60,#21,#62,3.);
|
|
31
|
+
#62= IFCDIRECTION((0.,0.,1.));
|
|
32
|
+
#63= IFCSHAPEREPRESENTATION(#20,'Body','SweptSolid',(#61));
|
|
33
|
+
#64= IFCPRODUCTDEFINITIONSHAPE($,$,(#63));
|
|
34
|
+
#70= IFCWALL('${wallA}',$,'Wall A',$,$,#50,#64,'tagA',$);
|
|
35
|
+
#71= IFCWALL('${wallB}',$,'Wall B',$,$,#50,#64,'tagB',$);
|
|
36
|
+
#80= IFCRELCONTAINEDINSPATIALSTRUCTURE('${guid('RELC')}',$,$,$,(#70,#71),#41);
|
|
37
|
+
ENDSEC;
|
|
38
|
+
END-ISO-10303-21;
|
|
39
|
+
`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* One entity from each `IfcRoot` branch, plus classes that are not `IfcRoot` at
|
|
43
|
+
* all and classes no schema registry knows.
|
|
44
|
+
*
|
|
45
|
+
* - `IfcTask` / `IfcActor` are `IfcObjectDefinition`s the columnar parser does
|
|
46
|
+
* not put in its `EntityTable` (they are not `IfcProduct` subtypes), so their
|
|
47
|
+
* GlobalId has to come from the STEP record.
|
|
48
|
+
* - `IfcRelDefinesByProperties` is an `IfcRelationship` and `IfcPropertySet` is
|
|
49
|
+
* an `IfcPropertyDefinition`: both carry GlobalIds, both stay out.
|
|
50
|
+
* - `IfcMaterial` has no GlobalId at all — its first attribute is a Name, which
|
|
51
|
+
* the parser's positional extraction stores in the table's GlobalId column.
|
|
52
|
+
* - `IfcVendorTask`, `IfcVendorWallType` and `IfcRelVendorLink` are in no schema
|
|
53
|
+
* registry. The parser's two name-based branches (`…TYPE`, `IFCREL…`) still
|
|
54
|
+
* take the last two into its table.
|
|
55
|
+
*/
|
|
56
|
+
export function scheduleModel(taskGuid) {
|
|
57
|
+
return `ISO-10303-21;
|
|
58
|
+
HEADER;
|
|
59
|
+
FILE_DESCRIPTION((''),'2;1');
|
|
60
|
+
FILE_NAME('m','2026',(''),(''),'','','');
|
|
61
|
+
FILE_SCHEMA(('IFC4'));
|
|
62
|
+
ENDSEC;
|
|
63
|
+
DATA;
|
|
64
|
+
#1= IFCPROJECT('${guid('PROJ')}',$,'Proj',$,$,$,$,(#20),#30);
|
|
65
|
+
#20= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-5,#21,$);
|
|
66
|
+
#21= IFCAXIS2PLACEMENT3D(#22,$,$);
|
|
67
|
+
#22= IFCCARTESIANPOINT((0.,0.,0.));
|
|
68
|
+
#30= IFCUNITASSIGNMENT((#31));
|
|
69
|
+
#31= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
|
|
70
|
+
#40= IFCLOCALPLACEMENT($,#21);
|
|
71
|
+
#41= IFCBUILDINGSTOREY('${guid('STOR')}',$,'L01',$,$,#40,$,$,.ELEMENT.,0.);
|
|
72
|
+
#70= IFCWALL('${guid('WALL')}',$,'Wall A',$,$,#40,$,'tagA',$);
|
|
73
|
+
#80= IFCMATERIAL('brick',$,$);
|
|
74
|
+
#81= IFCPROPERTYSET('${guid('PSET')}',$,'Pset_X',$,(#82));
|
|
75
|
+
#82= IFCPROPERTYSINGLEVALUE('P',$,IFCLABEL('v'),$);
|
|
76
|
+
#83= IFCRELDEFINESBYPROPERTIES('${guid('RELP')}',$,$,$,(#70),#81);
|
|
77
|
+
#90= IFCTASK('${taskGuid}',$,'Pour slab',$,$,$,$,'ID1',$,.F.,$,$,.CONSTRUCTION.);
|
|
78
|
+
#91= IFCACTOR('${guid('ACTR')}',$,'Site manager',$,$,#92,$);
|
|
79
|
+
#92= IFCPERSON($,'Doe','Jane',$,$,$,$,$);
|
|
80
|
+
#96= IFCRELCONTAINEDINSPATIALSTRUCTURE('${guid('RELC')}',$,$,$,(#70),#41);
|
|
81
|
+
#97= IFCVENDORTASK('${guid('VEND')}',$,'Custom',$);
|
|
82
|
+
#98= IFCVENDORWALLTYPE('${guid('VTYP')}',$,'Custom type',$,$,$,$,$,$,$);
|
|
83
|
+
#99= IFCRELVENDORLINK('${guid('VREL')}',$,$,$,(#70),#41);
|
|
84
|
+
ENDSEC;
|
|
85
|
+
END-ISO-10303-21;
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* An IFC2X3 file whose objects are classes IFC4 dropped, so the parser's IFC4
|
|
90
|
+
* codegen pin knows none of them.
|
|
91
|
+
*
|
|
92
|
+
* - `IfcMove` (an `IfcTask` subtype) and `IfcSpaceProgram` (an `IfcControl`)
|
|
93
|
+
* are `IfcObjectDefinition`s with real GlobalIds in slot 0, and are not
|
|
94
|
+
* `IfcProduct`s, so the `EntityTable` does not hold them.
|
|
95
|
+
* - `IfcSymbolStyle` is a *resource*: no GlobalId at all, a Name in slot 0. Its
|
|
96
|
+
* class name ends in `STYLE`, which is one of the parser's two name-based
|
|
97
|
+
* branches, so the table does hold it — with `hatch` in the GlobalId column.
|
|
98
|
+
* - `IfcGasTerminalType` is a real `IfcTypeObject`, reached through the other
|
|
99
|
+
* name-based branch (`…TYPE`).
|
|
100
|
+
*
|
|
101
|
+
* Deciding membership from the IFC4 pin alone gets all three wrong at once.
|
|
102
|
+
*/
|
|
103
|
+
export function legacyScheduleModel(moveGuid) {
|
|
104
|
+
return `ISO-10303-21;
|
|
105
|
+
HEADER;
|
|
106
|
+
FILE_DESCRIPTION((''),'2;1');
|
|
107
|
+
FILE_NAME('m','2026',(''),(''),'','','');
|
|
108
|
+
FILE_SCHEMA(('IFC2X3'));
|
|
109
|
+
ENDSEC;
|
|
110
|
+
DATA;
|
|
111
|
+
#1= IFCPROJECT('${guid('PROJ')}',$,'Proj',$,$,$,$,(#20),#30);
|
|
112
|
+
#20= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-5,#21,$);
|
|
113
|
+
#21= IFCAXIS2PLACEMENT3D(#22,$,$);
|
|
114
|
+
#22= IFCCARTESIANPOINT((0.,0.,0.));
|
|
115
|
+
#30= IFCUNITASSIGNMENT((#31));
|
|
116
|
+
#31= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
|
|
117
|
+
#40= IFCLOCALPLACEMENT($,#21);
|
|
118
|
+
#41= IFCBUILDINGSTOREY('${guid('STOR')}',$,'L01',$,$,#40,$,$,.ELEMENT.,0.);
|
|
119
|
+
#70= IFCWALLSTANDARDCASE('${guid('WALL')}',$,'Wall A',$,$,#40,$,'tagA');
|
|
120
|
+
#90= IFCMOVE('${moveGuid}',$,'Move A',$,$,'ID1',$,$,.F.,$,#41,#41,$);
|
|
121
|
+
#91= IFCSPACEPROGRAM('${guid('SPGM')}',$,'Program A',$,$,'SP1',$,$,$,$);
|
|
122
|
+
#92= IFCSYMBOLSTYLE('hatch',#93);
|
|
123
|
+
#93= IFCDEFINEDSYMBOL($,$);
|
|
124
|
+
#94= IFCGASTERMINALTYPE('${guid('GTTY')}',$,'GT',$,$,$,$,$,$,.GASAPPLIANCE.);
|
|
125
|
+
#96= IFCRELCONTAINEDINSPATIALSTRUCTURE('${guid('RELC')}',$,$,$,(#70),#41);
|
|
126
|
+
ENDSEC;
|
|
127
|
+
END-ISO-10303-21;
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The `Tag` scoping fixture (issue #2021), in both directions at once.
|
|
132
|
+
*
|
|
133
|
+
* Two `IfcWallType`s that agree on everything the fingerprint hashed before
|
|
134
|
+
* `Tag` did — same Name, same ElementType, same PredefinedType, no properties —
|
|
135
|
+
* and differ only in `Tag`. That is Duplex's eight `'800 mm'`
|
|
136
|
+
* `IfcFurnitureType`s reduced to two, and a type object has no geometry hash,
|
|
137
|
+
* so before #2021 nothing could separate them.
|
|
138
|
+
*
|
|
139
|
+
* Two `IfcWall`s built the same way, differing only in `Tag`. An occurrence's
|
|
140
|
+
* `Tag` is the authoring tool's element id rather than design content, so it
|
|
141
|
+
* must stay OUT of the hash — these two must keep hashing identically.
|
|
142
|
+
*/
|
|
143
|
+
export function typeTagModel() {
|
|
144
|
+
return `ISO-10303-21;
|
|
145
|
+
HEADER;
|
|
146
|
+
FILE_DESCRIPTION((''),'2;1');
|
|
147
|
+
FILE_NAME('m','2026',(''),(''),'','','');
|
|
148
|
+
FILE_SCHEMA(('IFC4'));
|
|
149
|
+
ENDSEC;
|
|
150
|
+
DATA;
|
|
151
|
+
#1= IFCPROJECT('${guid('PROJ')}',$,'Proj',$,$,$,$,(#20),#30);
|
|
152
|
+
#20= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-5,#21,$);
|
|
153
|
+
#21= IFCAXIS2PLACEMENT3D(#22,$,$);
|
|
154
|
+
#22= IFCCARTESIANPOINT((0.,0.,0.));
|
|
155
|
+
#30= IFCUNITASSIGNMENT((#31));
|
|
156
|
+
#31= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
|
|
157
|
+
#40= IFCLOCALPLACEMENT($,#21);
|
|
158
|
+
#41= IFCBUILDINGSTOREY('${guid('STOR')}',$,'L01',$,$,#40,$,$,.ELEMENT.,0.);
|
|
159
|
+
#50= IFCWALLTYPE('${guid('TYPA')}',$,'800 mm',$,$,$,$,'157200','800 mm',.STANDARD.);
|
|
160
|
+
#51= IFCWALLTYPE('${guid('TYPB')}',$,'800 mm',$,$,$,$,'157607','800 mm',.STANDARD.);
|
|
161
|
+
#70= IFCWALL('${guid('WALA')}',$,'Wall',$,$,#40,$,'tagA',.STANDARD.);
|
|
162
|
+
#71= IFCWALL('${guid('WALB')}',$,'Wall',$,$,#40,$,'tagB',.STANDARD.);
|
|
163
|
+
#80= IFCRELCONTAINEDINSPATIALSTRUCTURE('${guid('RELC')}',$,$,$,(#70,#71),#41);
|
|
164
|
+
ENDSEC;
|
|
165
|
+
END-ISO-10303-21;
|
|
166
|
+
`;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The same `Tag` question on a class the IFC4 codegen pin does not carry.
|
|
170
|
+
*
|
|
171
|
+
* `IfcRailType` is IFC4X3-only. Its inheritance chain resolves across the
|
|
172
|
+
* bundled schemas, so it is correctly in scope and correctly an `IfcTypeObject`
|
|
173
|
+
* — but its *attribute names* do not resolve through the pinned registry
|
|
174
|
+
* (`getAttributeNames('IfcRailType')` is empty, `getAttributeNamesAcrossSchemas`
|
|
175
|
+
* gives all ten with `Tag` at index 7). A `Tag` lookup that goes through the pin
|
|
176
|
+
* therefore finds nothing and silently no-ops on exactly the infrastructure
|
|
177
|
+
* classes IFC4X3 exists for, while passing every test written against IFC2X3 and
|
|
178
|
+
* IFC4. Same pinned-registry family as #2001/#2003.
|
|
179
|
+
*/
|
|
180
|
+
export function railTypeModel() {
|
|
181
|
+
return `ISO-10303-21;
|
|
182
|
+
HEADER;
|
|
183
|
+
FILE_DESCRIPTION((''),'2;1');
|
|
184
|
+
FILE_NAME('m','2026',(''),(''),'','','');
|
|
185
|
+
FILE_SCHEMA(('IFC4X3'));
|
|
186
|
+
ENDSEC;
|
|
187
|
+
DATA;
|
|
188
|
+
#1= IFCPROJECT('${guid('PROJ')}',$,'Proj',$,$,$,$,(#20),#30);
|
|
189
|
+
#20= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-5,#21,$);
|
|
190
|
+
#21= IFCAXIS2PLACEMENT3D(#22,$,$);
|
|
191
|
+
#22= IFCCARTESIANPOINT((0.,0.,0.));
|
|
192
|
+
#30= IFCUNITASSIGNMENT((#31));
|
|
193
|
+
#31= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
|
|
194
|
+
#50= IFCRAILTYPE('${guid('RALA')}',$,'60E1',$,$,$,$,'157200','60E1',.RACKRAIL.);
|
|
195
|
+
#51= IFCRAILTYPE('${guid('RALB')}',$,'60E1',$,$,$,$,'157607','60E1',.RACKRAIL.);
|
|
196
|
+
ENDSEC;
|
|
197
|
+
END-ISO-10303-21;
|
|
198
|
+
`;
|
|
199
|
+
}
|
|
200
|
+
export const BASE_MODEL = model(guid('OLDA'), guid('OLDB'));
|
|
201
|
+
/** Same building, re-exported: the two walls carry brand-new GlobalIds. */
|
|
202
|
+
export const HEAD_MODEL = model(guid('NEWA'), guid('NEWB'));
|
|
203
|
+
//# sourceMappingURL=diff-test-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-test-helpers.js","sourceRoot":"","sources":["../../src/commands/diff-test-helpers.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,kFAAkF;AAElF,yDAAyD;AACzD,MAAM,UAAU,IAAI,CAAC,QAAgB;IACnC,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClD,CAAC;AAED;;wDAEwD;AACxD,MAAM,UAAU,KAAK,CAAC,KAAa,EAAE,KAAa;IAChD,OAAO;;;;;;;kBAOS,IAAI,CAAC,MAAM,CAAC;;;;;;;0BAOJ,IAAI,CAAC,MAAM,CAAC;;;;;;;gBAOtB,KAAK;gBACL,KAAK;0CACqB,IAAI,CAAC,MAAM,CAAC;;;CAGrD,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO;;;;;;;kBAOS,IAAI,CAAC,MAAM,CAAC;;;;;;;0BAOJ,IAAI,CAAC,MAAM,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC;;uBAEL,IAAI,CAAC,MAAM,CAAC;;kCAED,IAAI,CAAC,MAAM,CAAC;gBAC9B,QAAQ;iBACP,IAAI,CAAC,MAAM,CAAC;;0CAEa,IAAI,CAAC,MAAM,CAAC;sBAChC,IAAI,CAAC,MAAM,CAAC;0BACR,IAAI,CAAC,MAAM,CAAC;yBACb,IAAI,CAAC,MAAM,CAAC;;;CAGpC,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,OAAO;;;;;;;kBAOS,IAAI,CAAC,MAAM,CAAC;;;;;;;0BAOJ,IAAI,CAAC,MAAM,CAAC;4BACV,IAAI,CAAC,MAAM,CAAC;gBACxB,QAAQ;wBACA,IAAI,CAAC,MAAM,CAAC;;;2BAGT,IAAI,CAAC,MAAM,CAAC;0CACG,IAAI,CAAC,MAAM,CAAC;;;CAGrD,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO;;;;;;;kBAOS,IAAI,CAAC,MAAM,CAAC;;;;;;;0BAOJ,IAAI,CAAC,MAAM,CAAC;oBAClB,IAAI,CAAC,MAAM,CAAC;oBACZ,IAAI,CAAC,MAAM,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC;gBACZ,IAAI,CAAC,MAAM,CAAC;0CACc,IAAI,CAAC,MAAM,CAAC;;;CAGrD,CAAC;AACF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;kBAOS,IAAI,CAAC,MAAM,CAAC;;;;;;oBAMV,IAAI,CAAC,MAAM,CAAC;oBACZ,IAAI,CAAC,MAAM,CAAC;;;CAG/B,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5D,2EAA2E;AAC3E,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC"}
|
package/dist/commands/diff.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAmCA,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAWxD;AAYD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8G/D"}
|
package/dist/commands/diff.js
CHANGED
|
@@ -6,18 +6,75 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Compare two IFC files and report differences in entity counts,
|
|
8
8
|
* types, and optionally property values.
|
|
9
|
+
*
|
|
10
|
+
* `--by-entity` adds a GlobalId-level added/removed/common count over the
|
|
11
|
+
* entities `diff-scope.ts` decides are comparable, which is the same set
|
|
12
|
+
* `--by-content` fingerprints — one answer about which entities a diff is
|
|
13
|
+
* about, for both modes of the command.
|
|
14
|
+
*
|
|
15
|
+
* `--by-content` switches to the `@ifc-lite/diff` engine with content-keyed
|
|
16
|
+
* matching and the identity-map sidecar (issue #1891) — see `diff-content.ts`.
|
|
9
17
|
*/
|
|
10
18
|
import { loadIfcFile } from '../loader.js';
|
|
11
|
-
import { hasFlag, fatal, printJson, formatTable } from '../output.js';
|
|
12
|
-
import { EntityNode } from '@ifc-lite/query';
|
|
19
|
+
import { hasFlag, getFlag, fatal, printJson, formatTable } from '../output.js';
|
|
13
20
|
import { IFC_ENTITY_NAMES } from '@ifc-lite/data';
|
|
21
|
+
import { contentDiffCommand } from './diff-content.js';
|
|
22
|
+
import { comparableGlobalIds } from './diff-scope.js';
|
|
23
|
+
const USAGE = 'Usage: ifc-lite diff <file1.ifc> <file2.ifc> [--json] [--by-entity]\n' +
|
|
24
|
+
' [--by-content] [--identity-out <map.json>] [--identity-in <map.json>]';
|
|
25
|
+
/** Flags that consume the following argument, so it is never mistaken for a
|
|
26
|
+
* positional file path. Deliberately only the flags this command owns: the
|
|
27
|
+
* shared `args.filter(a => !a.startsWith('-'))` idiom would have swallowed
|
|
28
|
+
* `--identity-out map.json` as a third file. */
|
|
29
|
+
const VALUE_FLAGS = new Set(['--identity-out', '--identity-in']);
|
|
30
|
+
export function diffPositionals(args) {
|
|
31
|
+
const positional = [];
|
|
32
|
+
for (let i = 0; i < args.length; i++) {
|
|
33
|
+
const arg = args[i];
|
|
34
|
+
if (arg.startsWith('-')) {
|
|
35
|
+
if (VALUE_FLAGS.has(arg))
|
|
36
|
+
i++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
positional.push(arg);
|
|
40
|
+
}
|
|
41
|
+
return positional;
|
|
42
|
+
}
|
|
43
|
+
/** Read a path-valued flag, rejecting a missing value or one that is obviously
|
|
44
|
+
* the next flag — `--identity-out --json` would otherwise write a file called
|
|
45
|
+
* `--json`. */
|
|
46
|
+
function identityPath(args, flag) {
|
|
47
|
+
if (!hasFlag(args, flag))
|
|
48
|
+
return undefined;
|
|
49
|
+
const value = getFlag(args, flag);
|
|
50
|
+
if (value === undefined || value.startsWith('-'))
|
|
51
|
+
fatal(`${flag} requires a file path`);
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
14
54
|
export async function diffCommand(args) {
|
|
15
|
-
const positional = args
|
|
16
|
-
|
|
17
|
-
|
|
55
|
+
const positional = diffPositionals(args);
|
|
56
|
+
// Exactly two, not "at least two". A third path is never a diff the command
|
|
57
|
+
// can do, and silently dropping it is how `diff a.ifc b.ifc c.ifc` comes back
|
|
58
|
+
// with a confident answer about the wrong pair of files.
|
|
59
|
+
if (positional.length !== 2)
|
|
60
|
+
fatal(USAGE);
|
|
18
61
|
const [file1, file2] = positional;
|
|
19
62
|
const jsonOutput = hasFlag(args, '--json');
|
|
20
63
|
const byEntity = hasFlag(args, '--by-entity');
|
|
64
|
+
// The identity-map flags only mean anything on the engine path, so they imply
|
|
65
|
+
// it rather than being silently ignored next to the type-count diff.
|
|
66
|
+
const identityOut = identityPath(args, '--identity-out');
|
|
67
|
+
const identityIn = identityPath(args, '--identity-in');
|
|
68
|
+
if (hasFlag(args, '--by-content') || identityOut !== undefined || identityIn !== undefined) {
|
|
69
|
+
await contentDiffCommand({
|
|
70
|
+
basePath: file1,
|
|
71
|
+
headPath: file2,
|
|
72
|
+
identityIn,
|
|
73
|
+
identityOut,
|
|
74
|
+
json: jsonOutput,
|
|
75
|
+
});
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
21
78
|
process.stderr.write(`Loading files...\n`);
|
|
22
79
|
const store1 = await loadIfcFile(file1);
|
|
23
80
|
const store2 = await loadIfcFile(file2);
|
|
@@ -42,27 +99,16 @@ export async function diffCommand(args) {
|
|
|
42
99
|
}
|
|
43
100
|
}
|
|
44
101
|
typeDiffs.sort((a, b) => Math.abs(b.delta) - Math.abs(a.delta));
|
|
45
|
-
// Entity-level comparison by GlobalId
|
|
102
|
+
// Entity-level comparison by GlobalId, over the entities `diff-scope.ts`
|
|
103
|
+
// says are comparable at all. Asking every row of the entity index for a
|
|
104
|
+
// GlobalId instead — which is what this did — answered with a *Name* for
|
|
105
|
+
// every resource entity whose STEP record starts with one, so two materials
|
|
106
|
+
// sharing a name were compared as one entity, and it counted relationships
|
|
107
|
+
// and property sets whose identity belongs to the things they connect.
|
|
46
108
|
let entityDiff;
|
|
47
109
|
if (byEntity) {
|
|
48
|
-
const globalIds1 =
|
|
49
|
-
const globalIds2 =
|
|
50
|
-
for (const [, ids] of store1.entityIndex.byType) {
|
|
51
|
-
for (const id of ids) {
|
|
52
|
-
const node = new EntityNode(store1, id);
|
|
53
|
-
const gid = node.globalId;
|
|
54
|
-
if (gid)
|
|
55
|
-
globalIds1.add(gid);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
for (const [, ids] of store2.entityIndex.byType) {
|
|
59
|
-
for (const id of ids) {
|
|
60
|
-
const node = new EntityNode(store2, id);
|
|
61
|
-
const gid = node.globalId;
|
|
62
|
-
if (gid)
|
|
63
|
-
globalIds2.add(gid);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
110
|
+
const globalIds1 = comparableGlobalIds(store1);
|
|
111
|
+
const globalIds2 = comparableGlobalIds(store2);
|
|
66
112
|
const added = [...globalIds2].filter(g => !globalIds1.has(g));
|
|
67
113
|
const removed = [...globalIds1].filter(g => !globalIds2.has(g));
|
|
68
114
|
const common = [...globalIds1].filter(g => globalIds2.has(g)).length;
|
|
@@ -98,7 +144,7 @@ export async function diffCommand(args) {
|
|
|
98
144
|
process.stdout.write(` No type differences.\n`);
|
|
99
145
|
}
|
|
100
146
|
if (entityDiff) {
|
|
101
|
-
process.stdout.write(`\n Entity comparison (by GlobalId):\n`);
|
|
147
|
+
process.stdout.write(`\n Entity comparison (by GlobalId, every IfcObjectDefinition):\n`);
|
|
102
148
|
process.stdout.write(` Common: ${entityDiff.common}\n`);
|
|
103
149
|
process.stdout.write(` Added: ${entityDiff.added.length}\n`);
|
|
104
150
|
process.stdout.write(` Removed: ${entityDiff.removed.length}\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"AA2BA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"AA2BA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiH/D"}
|
package/dist/commands/eval.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* ifc-lite eval model.ifc "bim.query().byType('IfcDoor').toArray().map(d => d.name)"
|
|
17
17
|
*/
|
|
18
18
|
import { createHeadlessContext, createStreamingContext } from '../loader.js';
|
|
19
|
-
import { printJson, fatal, hasFlag, getFlag, validateViewerPort } from '../output.js';
|
|
19
|
+
import { printJson, fatal, hasFlag, getFlag, validateViewerPort, validateLimit } from '../output.js';
|
|
20
20
|
/** Known flags that take a value argument */
|
|
21
21
|
const EVAL_VALUE_FLAGS = new Set(['--type', '--limit', '--viewer']);
|
|
22
22
|
/** Known boolean flags (no value) */
|
|
@@ -72,8 +72,12 @@ export async function evalCommand(args) {
|
|
|
72
72
|
return 'Ifc' + trimmed;
|
|
73
73
|
});
|
|
74
74
|
let entities = bim.query().byType(...types).toArray();
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
// Validated, not parseInt'd: a non-numeric --limit yields NaN and
|
|
76
|
+
// slice(0, NaN) returns [], so a typo silently evaluated nothing and
|
|
77
|
+
// reported success. Same guard as export --limit.
|
|
78
|
+
const evalLimit = validateLimit(limitStr);
|
|
79
|
+
if (evalLimit !== undefined)
|
|
80
|
+
entities = entities.slice(0, evalLimit);
|
|
77
81
|
const results = [];
|
|
78
82
|
const evalFn = buildEvalFunction(expression, ['bim', 'ref', 'entity']);
|
|
79
83
|
for (const entity of entities) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAuKA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2PjE"}
|
package/dist/commands/export.js
CHANGED
|
@@ -13,7 +13,7 @@ import { basename } from 'node:path';
|
|
|
13
13
|
import { GeometryProcessor, isNoRenderGeometryError } from '@ifc-lite/geometry';
|
|
14
14
|
import { countGlbMeshes } from '@ifc-lite/export';
|
|
15
15
|
import { createHeadlessContext } from '../loader.js';
|
|
16
|
-
import { getFlag, hasFlag, fatal, writeOutput } from '../output.js';
|
|
16
|
+
import { getFlag, hasFlag, fatal, writeOutput, validateLimit } from '../output.js';
|
|
17
17
|
import { logger } from '../logger.js';
|
|
18
18
|
import { formatGeometryReport, NO_DIAGNOSTICS_LINE } from '../geometry-report.js';
|
|
19
19
|
/**
|
|
@@ -121,10 +121,19 @@ function columnValueToCsv(value) {
|
|
|
121
121
|
/**
|
|
122
122
|
* Resolve the raw IFC bytes (parsed store source, or re-read from disk) plus a
|
|
123
123
|
* one-shot wasm GeometryProcessor for the Rust-backed exporters (OBJ / glTF / JSON-LD).
|
|
124
|
+
*
|
|
125
|
+
* Every Rust exporter below takes the WHOLE file, so the source is genuinely
|
|
126
|
+
* materialised here (#2183). It is handed back rather than scoped through a
|
|
127
|
+
* callback because the caller is one `switch` arm of a single CLI invocation
|
|
128
|
+
* that also runs the optional diagnostics pass over the same bytes; the buffer
|
|
129
|
+
* dies with the command.
|
|
124
130
|
*/
|
|
125
131
|
async function rustExportContext(store, filePath) {
|
|
126
|
-
let bytes
|
|
127
|
-
if (
|
|
132
|
+
let bytes;
|
|
133
|
+
if (store.source.byteLength > 0) {
|
|
134
|
+
bytes = store.source.materialize();
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
128
137
|
const buf = await readFile(filePath);
|
|
129
138
|
bytes = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
130
139
|
}
|
|
@@ -154,26 +163,32 @@ export async function exportCommand(args) {
|
|
|
154
163
|
const limit = getFlag(args, '--limit');
|
|
155
164
|
const propFilter = getFlag(args, '--where');
|
|
156
165
|
const storeyFilter = getFlag(args, '--storey');
|
|
166
|
+
// IFCX and USD are whole-model, geometry-backed exports: they never honor the
|
|
167
|
+
// entity-isolation filters, so an invalid/zero-match filter must NOT abort the
|
|
168
|
+
// export — skip filter processing entirely and just note it below.
|
|
169
|
+
const wholeModelFormat = format === 'ifcx' || format === 'usd';
|
|
170
|
+
const filterRequested = !!(type || propFilter || storeyFilter || limit);
|
|
157
171
|
if (!filePath)
|
|
158
|
-
fatal('Usage: ifc-lite export <file.ifc> --format csv|json|ifc|obj|gltf|glb|jsonld|step|ifcx|hbjson [--type IfcWall] [--columns Name,Type,GlobalId] [--where PsetName.Prop=Value] [--storey Name] [--name Model] [--out file]');
|
|
172
|
+
fatal('Usage: ifc-lite export <file.ifc> --format csv|json|ifc|obj|gltf|glb|jsonld|step|ifcx|usd|hbjson [--type IfcWall] [--columns Name,Type,GlobalId] [--where PsetName.Prop=Value] [--storey Name] [--name Model] [--out file]');
|
|
159
173
|
// B9/F6: Auto-prefix Ifc
|
|
160
174
|
if (type) {
|
|
161
175
|
type = normalizeTypeName(type);
|
|
162
176
|
}
|
|
163
177
|
const { bim, store } = await createHeadlessContext(filePath);
|
|
164
|
-
// Build entity query
|
|
178
|
+
// Build entity query. Whole-model formats (ifcx/usd) skip all filtering so a bad or
|
|
179
|
+
// zero-match filter can't abort the export.
|
|
165
180
|
let q = bim.query();
|
|
166
|
-
if (type) {
|
|
181
|
+
if (type && !wholeModelFormat) {
|
|
167
182
|
q = q.byType(...type.split(','));
|
|
168
183
|
}
|
|
169
|
-
if (propFilter) {
|
|
184
|
+
if (propFilter && !wholeModelFormat) {
|
|
170
185
|
const parsed = parseWhereFilter(propFilter);
|
|
171
186
|
q = q.where(parsed.psetName, parsed.propName, parsed.operator, parsed.value);
|
|
172
187
|
}
|
|
173
188
|
// Don't apply limit to the query yet — storey filtering must happen first
|
|
174
189
|
let entities = q.toArray();
|
|
175
190
|
// B4: --storey filter (applied before limit so --limit restricts storey-filtered results)
|
|
176
|
-
if (storeyFilter) {
|
|
191
|
+
if (storeyFilter && !wholeModelFormat) {
|
|
177
192
|
const storeys = bim.storeys();
|
|
178
193
|
const matchedStorey = storeys.find((s) => s.name === storeyFilter ||
|
|
179
194
|
s.name.toLowerCase().includes(storeyFilter.toLowerCase()) ||
|
|
@@ -186,9 +201,13 @@ export async function exportCommand(args) {
|
|
|
186
201
|
const storeyIds = new Set(contained.map((e) => e.ref.expressId));
|
|
187
202
|
entities = entities.filter((e) => storeyIds.has(e.ref.expressId));
|
|
188
203
|
}
|
|
189
|
-
// Apply limit after storey filtering
|
|
190
|
-
|
|
191
|
-
|
|
204
|
+
// Apply limit after storey filtering. A non-numeric/negative --limit used
|
|
205
|
+
// to fall through to Array.prototype.slice(0, NaN), which silently returns
|
|
206
|
+
// an empty array — a typo'd flag turned into a zero-row export reported as
|
|
207
|
+
// success. validateLimit() rejects that loudly instead.
|
|
208
|
+
const parsedLimit = validateLimit(limit);
|
|
209
|
+
if (parsedLimit !== undefined) {
|
|
210
|
+
entities = entities.slice(0, parsedLimit);
|
|
192
211
|
}
|
|
193
212
|
const refs = entities.map((e) => e.ref);
|
|
194
213
|
const columns = columnsStr
|
|
@@ -252,8 +271,11 @@ export async function exportCommand(args) {
|
|
|
252
271
|
case 'glb':
|
|
253
272
|
case 'jsonld':
|
|
254
273
|
case 'ifcx':
|
|
274
|
+
case 'usd':
|
|
255
275
|
case 'step': {
|
|
256
|
-
|
|
276
|
+
// Whole-model formats (ifcx/usd) never isolate, so filters were skipped above and
|
|
277
|
+
// must not gate the export here — only the isolating formats treat a filter as active.
|
|
278
|
+
const filterActive = !wholeModelFormat && filterRequested;
|
|
257
279
|
const isolated = filterActive
|
|
258
280
|
? new Uint32Array(refs.map((r) => r.expressId))
|
|
259
281
|
: new Uint32Array();
|
|
@@ -263,9 +285,9 @@ export async function exportCommand(args) {
|
|
|
263
285
|
if (filterActive && isolated.length === 0) {
|
|
264
286
|
fatal('Filter matched 0 entities — nothing to export. Check --type/--storey/--where/--limit.');
|
|
265
287
|
}
|
|
266
|
-
// IFCX
|
|
267
|
-
if (
|
|
268
|
-
process.stderr.write(
|
|
288
|
+
// IFCX / USD are whole-model exports; a requested filter is ignored, not an error.
|
|
289
|
+
if (filterRequested && wholeModelFormat) {
|
|
290
|
+
process.stderr.write(`Note: --type/--storey/--where/--limit do not apply to ${format.toUpperCase()}; exporting the whole model.\n`);
|
|
269
291
|
}
|
|
270
292
|
// --profile: attribute wall-time between the per-invocation wasm
|
|
271
293
|
// bootstrap (GeometryProcessor init) and the export itself - the
|
|
@@ -284,6 +306,13 @@ export async function exportCommand(args) {
|
|
|
284
306
|
fatal('IFCX export failed (geometry pipeline not initialized)');
|
|
285
307
|
await writeOutput(out, outPath);
|
|
286
308
|
}
|
|
309
|
+
else if (format === 'usd') {
|
|
310
|
+
// OpenUSD (.usda ASCII) — whole-model Z-up USD stage (geometry-backed).
|
|
311
|
+
const out = gp.exportUsd(bytes);
|
|
312
|
+
if (out == null)
|
|
313
|
+
fatal('USD export failed (geometry pipeline not initialized)');
|
|
314
|
+
await writeOutput(out, outPath);
|
|
315
|
+
}
|
|
287
316
|
else if (format === 'step') {
|
|
288
317
|
// Rust faithful re-serialization (+ reference-closed subset when filtered).
|
|
289
318
|
const schema = getFlag(args, '--schema') ?? '';
|
|
@@ -373,7 +402,7 @@ export async function exportCommand(args) {
|
|
|
373
402
|
break;
|
|
374
403
|
}
|
|
375
404
|
default:
|
|
376
|
-
fatal(`Unknown format: ${format}. Supported: csv, json, ifc, obj, gltf, glb, jsonld, step, ifcx, hbjson`);
|
|
405
|
+
fatal(`Unknown format: ${format}. Supported: csv, json, ifc, obj, gltf, glb, jsonld, step, ifcx, usd, hbjson`);
|
|
377
406
|
}
|
|
378
407
|
}
|
|
379
408
|
//# sourceMappingURL=export.js.map
|