@ifc-lite/create 1.16.4 → 2.0.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/README.md +1 -1
- package/dist/ifc-creator.d.ts +37 -1
- package/dist/ifc-creator.d.ts.map +1 -1
- package/dist/ifc-creator.js +96 -33
- package/dist/ifc-creator.js.map +1 -1
- package/dist/in-store/_emit-helpers.d.ts +18 -2
- package/dist/in-store/_emit-helpers.d.ts.map +1 -1
- package/dist/in-store/_emit-helpers.js +6 -4
- package/dist/in-store/_emit-helpers.js.map +1 -1
- package/dist/in-store/anchor.d.ts +11 -0
- package/dist/in-store/anchor.d.ts.map +1 -1
- package/dist/in-store/anchor.js.map +1 -1
- package/dist/in-store/beam.js +2 -2
- package/dist/in-store/beam.js.map +1 -1
- package/dist/in-store/column.js +2 -2
- package/dist/in-store/column.js.map +1 -1
- package/dist/in-store/door.js +2 -2
- package/dist/in-store/door.js.map +1 -1
- package/dist/in-store/duplicate.d.ts +27 -0
- package/dist/in-store/duplicate.d.ts.map +1 -1
- package/dist/in-store/duplicate.js +3 -3
- package/dist/in-store/duplicate.js.map +1 -1
- package/dist/in-store/generate-spaces-all.d.ts +6 -0
- package/dist/in-store/generate-spaces-all.d.ts.map +1 -1
- package/dist/in-store/generate-spaces-all.js +1 -0
- package/dist/in-store/generate-spaces-all.js.map +1 -1
- package/dist/in-store/generate-spaces.d.ts +7 -0
- package/dist/in-store/generate-spaces.d.ts.map +1 -1
- package/dist/in-store/generate-spaces.js +2 -0
- package/dist/in-store/generate-spaces.js.map +1 -1
- package/dist/in-store/member.js +2 -2
- package/dist/in-store/member.js.map +1 -1
- package/dist/in-store/plate.js +2 -2
- package/dist/in-store/plate.js.map +1 -1
- package/dist/in-store/roof.js +2 -2
- package/dist/in-store/roof.js.map +1 -1
- package/dist/in-store/slab.js +2 -2
- package/dist/in-store/slab.js.map +1 -1
- package/dist/in-store/space.js +3 -3
- package/dist/in-store/space.js.map +1 -1
- package/dist/in-store/wall.js +2 -2
- package/dist/in-store/wall.js.map +1 -1
- package/dist/in-store/window.js +2 -2
- package/dist/in-store/window.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +19 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ifc-lite/create
|
|
2
2
|
|
|
3
|
-
Create valid IFC4 STEP files from scratch, programmatically. `IfcCreator` builds a complete spatial structure (project, site, building, storeys) and adds building elements with real geometry, property sets, quantities, and materials. Inputs are in metres
|
|
3
|
+
Create valid IFC4 STEP files from scratch, programmatically. `IfcCreator` builds a complete spatial structure (project, site, building, storeys) and adds building elements with real geometry, property sets, quantities, and materials. Inputs are in metres. Element coordinates are relative to the storey you add the element to: the storey placement carries `Elevation` and every element chains to it, so an element standing on a storey at `Elevation: 3` is created with `Z = 0`.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
package/dist/ifc-creator.d.ts
CHANGED
|
@@ -14,6 +14,27 @@
|
|
|
14
14
|
* All values in metres unless LengthUnit is overridden.
|
|
15
15
|
*/
|
|
16
16
|
import type { Point3D, Point2D, Placement3D, ElementAttributes, ProfileDef, GenericElementParams, AxisElementParams, WallParams, SlabParams, ColumnParams, BeamParams, StairParams, RoofParams, GableRoofParams, WallDoorParams, WallWindowParams, DoorParams, WindowParams, RampParams, RailingParams, PlateParams, MemberParams, FootingParams, PileParams, SpaceParams, CurtainWallParams, FurnishingParams, ProxyParams, ProjectParams, StoreyParams, PropertySetDef, QuantitySetDef, MaterialDef, WorkScheduleParams, WorkPlanParams, TaskParams, SequenceParams, CreateResult } from './types.js';
|
|
17
|
+
/**
|
|
18
|
+
* PLACEMENT CONTRACT
|
|
19
|
+
*
|
|
20
|
+
* Every `addIfcXxx(storeyId, …)` / `addElement(storeyId, …)` method takes the
|
|
21
|
+
* storey as its first argument and emits an `IfcRelContainedInSpatialStructure`
|
|
22
|
+
* putting the product in that storey. The product's `IfcLocalPlacement` is
|
|
23
|
+
* therefore chained to the STOREY's placement, never to the world: the
|
|
24
|
+
* placement hierarchy has to agree with the containment hierarchy, or moving a
|
|
25
|
+
* storey leaves its own contents behind.
|
|
26
|
+
*
|
|
27
|
+
* Consequence for callers: **coordinates passed to these methods are
|
|
28
|
+
* storey-relative.** `IfcBuildingStorey.Elevation` is applied exactly once, by
|
|
29
|
+
* the storey's own placement (`[0, 0, Elevation]`, the only placement in this
|
|
30
|
+
* class that is chained to the world). A wall whose floor sits on a storey at
|
|
31
|
+
* `Elevation: 3` is created with `Z = 0`, not `Z = 3`.
|
|
32
|
+
*
|
|
33
|
+
* Before 2.0.0 only `addIfcWall`, `addIfcSlab`, `addIfcColumn`, `addIfcBeam`,
|
|
34
|
+
* `addIfcStair`, `addIfcRoof` and `addIfcGableRoof` behaved this way; the other
|
|
35
|
+
* 21 constructors chained to the world, so a caller mixing them on a storey
|
|
36
|
+
* with a non-zero elevation got two different datums in one model.
|
|
37
|
+
*/
|
|
17
38
|
export declare class IfcCreator {
|
|
18
39
|
private nextId;
|
|
19
40
|
private lines;
|
|
@@ -50,12 +71,27 @@ export declare class IfcCreator {
|
|
|
50
71
|
/** Wall expressId → wall thickness */
|
|
51
72
|
private wallThicknesses;
|
|
52
73
|
private projectParams;
|
|
74
|
+
/** Fixed creation instant (epoch ms) for header/owner-history; null = wall clock. */
|
|
75
|
+
private readonly fixedTimestampMs;
|
|
76
|
+
/** Deterministic GlobalId source; null = platform CSPRNG. */
|
|
77
|
+
private readonly guidSource;
|
|
53
78
|
constructor(params?: ProjectParams);
|
|
79
|
+
/** The creation instant used everywhere: the fixed Timestamp when provided, else the wall clock. */
|
|
80
|
+
private nowMs;
|
|
54
81
|
/** Generate a spec-valid 22-character IFC GlobalId (canonical encoder from @ifc-lite/encoding). */
|
|
55
82
|
private newGlobalId;
|
|
56
83
|
/** Add a building storey. Returns the storey expressId for use with element creation. */
|
|
57
84
|
addIfcBuildingStorey(params: StoreyParams): number;
|
|
58
|
-
/**
|
|
85
|
+
/**
|
|
86
|
+
* The `IfcLocalPlacement` every product of this storey chains to.
|
|
87
|
+
*
|
|
88
|
+
* Throws on an unknown storey rather than falling back to the world
|
|
89
|
+
* placement: the fallback silently produced a product on a different datum
|
|
90
|
+
* from its siblings, which is the exact failure this parent is here to make
|
|
91
|
+
* impossible. `trackElement` rejects the same id a few lines later anyway,
|
|
92
|
+
* so failing here only means the half-built placement entities are never
|
|
93
|
+
* emitted.
|
|
94
|
+
*/
|
|
59
95
|
private getStoreyPlacement;
|
|
60
96
|
/**
|
|
61
97
|
* Create a wall from Start to End with given Thickness and Height.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc-creator.d.ts","sourceRoot":"","sources":["../src/ifc-creator.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,OAAO,EAAE,OAAO,EAAE,WAAW,EAC7B,iBAAiB,EAAE,UAAU,EAC7B,oBAAoB,EAAE,iBAAiB,EACvC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAC1F,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EACrF,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EACpD,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,WAAW,EAC7D,aAAa,EAA8B,YAAY,EACvD,cAAc,EAAe,cAAc,EAC3C,WAAW,EACX,kBAAkB,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAC/C,YAAY,EAC5B,MAAM,YAAY,CAAC;AAoCpB,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,MAAM,CAA+B;IAE7C,gFAAgF;IAChF,OAAO,CAAC,aAAa,CAAqB;IAG1C,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,gBAAgB,CAAK;IAG7B,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,cAAc,CAAK;IAG3B,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,aAAa,CAA2E;IAGhG,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,gBAAgB,CAAkC;IAG1D,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,cAAc,CAAoC;IAC1D,uEAAuE;IACvE,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,sDAAsD;IACtD,OAAO,CAAC,cAAc,CAAkC;IACxD,4CAA4C;IAC5C,OAAO,CAAC,cAAc,CAAkC;IACxD,sCAAsC;IACtC,OAAO,CAAC,eAAe,CAAkC;IAEzD,OAAO,CAAC,aAAa,CAAgB;
|
|
1
|
+
{"version":3,"file":"ifc-creator.d.ts","sourceRoot":"","sources":["../src/ifc-creator.ts"],"names":[],"mappings":"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"}
|
package/dist/ifc-creator.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
import { esc, stepLine, num, vecLen, vecNorm, vecCross, NON_ELEMENT_TYPES, } from './ifc-creator-math.js';
|
|
5
|
-
import { generateIfcGuid } from '@ifc-lite/encoding';
|
|
5
|
+
import { generateIfcGuid, isValidIfcGuid } from '@ifc-lite/encoding';
|
|
6
6
|
// ============================================================================
|
|
7
7
|
// STEP attribute helpers (scheduling — optional strings / enums / numbers)
|
|
8
8
|
// ============================================================================
|
|
@@ -25,6 +25,27 @@ function optReal(v) {
|
|
|
25
25
|
// ============================================================================
|
|
26
26
|
// IfcCreator
|
|
27
27
|
// ============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* PLACEMENT CONTRACT
|
|
30
|
+
*
|
|
31
|
+
* Every `addIfcXxx(storeyId, …)` / `addElement(storeyId, …)` method takes the
|
|
32
|
+
* storey as its first argument and emits an `IfcRelContainedInSpatialStructure`
|
|
33
|
+
* putting the product in that storey. The product's `IfcLocalPlacement` is
|
|
34
|
+
* therefore chained to the STOREY's placement, never to the world: the
|
|
35
|
+
* placement hierarchy has to agree with the containment hierarchy, or moving a
|
|
36
|
+
* storey leaves its own contents behind.
|
|
37
|
+
*
|
|
38
|
+
* Consequence for callers: **coordinates passed to these methods are
|
|
39
|
+
* storey-relative.** `IfcBuildingStorey.Elevation` is applied exactly once, by
|
|
40
|
+
* the storey's own placement (`[0, 0, Elevation]`, the only placement in this
|
|
41
|
+
* class that is chained to the world). A wall whose floor sits on a storey at
|
|
42
|
+
* `Elevation: 3` is created with `Z = 0`, not `Z = 3`.
|
|
43
|
+
*
|
|
44
|
+
* Before 2.0.0 only `addIfcWall`, `addIfcSlab`, `addIfcColumn`, `addIfcBeam`,
|
|
45
|
+
* `addIfcStair`, `addIfcRoof` and `addIfcGableRoof` behaved this way; the other
|
|
46
|
+
* 21 constructors chained to the world, so a caller mixing them on a storey
|
|
47
|
+
* with a non-zero elevation got two different datums in one model.
|
|
48
|
+
*/
|
|
28
49
|
export class IfcCreator {
|
|
29
50
|
nextId = 1;
|
|
30
51
|
lines = [];
|
|
@@ -67,19 +88,48 @@ export class IfcCreator {
|
|
|
67
88
|
/** Wall expressId → wall thickness */
|
|
68
89
|
wallThicknesses = new Map();
|
|
69
90
|
projectParams;
|
|
91
|
+
/** Fixed creation instant (epoch ms) for header/owner-history; null = wall clock. */
|
|
92
|
+
fixedTimestampMs;
|
|
93
|
+
/** Deterministic GlobalId source; null = platform CSPRNG. */
|
|
94
|
+
guidSource;
|
|
70
95
|
constructor(params = {}) {
|
|
71
96
|
this.projectParams = params;
|
|
72
97
|
this.schema = params.Schema ?? 'IFC4';
|
|
98
|
+
this.fixedTimestampMs = params.Timestamp === undefined
|
|
99
|
+
? null
|
|
100
|
+
: typeof params.Timestamp === 'number' ? params.Timestamp : params.Timestamp.getTime();
|
|
101
|
+
// Finite is not enough: epoch-ms past ±8.64e15 is outside the Date range,
|
|
102
|
+
// so it survives `Number.isFinite` and only blows up later in
|
|
103
|
+
// `toISOString()` while writing the header. Reject it here, where the
|
|
104
|
+
// message can still name the offending parameter.
|
|
105
|
+
if (this.fixedTimestampMs !== null
|
|
106
|
+
&& (!Number.isFinite(this.fixedTimestampMs) || Number.isNaN(new Date(this.fixedTimestampMs).getTime()))) {
|
|
107
|
+
throw new Error('IfcCreator: Timestamp must be a finite epoch-milliseconds number within the Date range, or a valid Date');
|
|
108
|
+
}
|
|
109
|
+
this.guidSource = params.GuidSource ?? null;
|
|
73
110
|
this.buildPreamble(params);
|
|
74
111
|
}
|
|
112
|
+
/** The creation instant used everywhere: the fixed Timestamp when provided, else the wall clock. */
|
|
113
|
+
nowMs() {
|
|
114
|
+
return this.fixedTimestampMs ?? Date.now();
|
|
115
|
+
}
|
|
75
116
|
/** Generate a spec-valid 22-character IFC GlobalId (canonical encoder from @ifc-lite/encoding). */
|
|
76
117
|
newGlobalId() {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
118
|
+
const generate = this.guidSource ?? generateIfcGuid;
|
|
119
|
+
// Bounded retry: with the default CSPRNG a collision is astronomically
|
|
120
|
+
// unlikely; with a user GuidSource the bound turns a repeating source into
|
|
121
|
+
// a clear error instead of an infinite loop.
|
|
122
|
+
for (let attempt = 0; attempt < 100; attempt += 1) {
|
|
123
|
+
const result = generate();
|
|
124
|
+
if (this.guidSource !== null && !isValidIfcGuid(result)) {
|
|
125
|
+
throw new Error(`IfcCreator: GuidSource returned an invalid IFC GlobalId: '${result}' (must be 22 characters of the IFC base64 alphabet)`);
|
|
126
|
+
}
|
|
127
|
+
if (!this.usedGlobalIds.has(result)) {
|
|
128
|
+
this.usedGlobalIds.add(result);
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
throw new Error('IfcCreator: could not generate a unique GlobalId after 100 attempts - the GuidSource is repeating already-used values');
|
|
83
133
|
}
|
|
84
134
|
// ============================================================================
|
|
85
135
|
// Public API — Spatial Structure
|
|
@@ -102,9 +152,22 @@ export class IfcCreator {
|
|
|
102
152
|
this.entities.push({ expressId: id, type: 'IfcBuildingStorey', Name: name });
|
|
103
153
|
return id;
|
|
104
154
|
}
|
|
105
|
-
/**
|
|
155
|
+
/**
|
|
156
|
+
* The `IfcLocalPlacement` every product of this storey chains to.
|
|
157
|
+
*
|
|
158
|
+
* Throws on an unknown storey rather than falling back to the world
|
|
159
|
+
* placement: the fallback silently produced a product on a different datum
|
|
160
|
+
* from its siblings, which is the exact failure this parent is here to make
|
|
161
|
+
* impossible. `trackElement` rejects the same id a few lines later anyway,
|
|
162
|
+
* so failing here only means the half-built placement entities are never
|
|
163
|
+
* emitted.
|
|
164
|
+
*/
|
|
106
165
|
getStoreyPlacement(storeyId) {
|
|
107
|
-
|
|
166
|
+
const placementId = this.storeyPlacements.get(storeyId);
|
|
167
|
+
if (placementId === undefined) {
|
|
168
|
+
throw new Error(`Unknown storeyId #${storeyId} — call addIfcBuildingStorey() first`);
|
|
169
|
+
}
|
|
170
|
+
return placementId;
|
|
108
171
|
}
|
|
109
172
|
// ============================================================================
|
|
110
173
|
// Public API — Building Elements
|
|
@@ -470,7 +533,7 @@ export class IfcCreator {
|
|
|
470
533
|
* Create a door element. Width × Height × Thickness panel.
|
|
471
534
|
*/
|
|
472
535
|
addIfcDoor(storeyId, params) {
|
|
473
|
-
const placementId = this.addLocalPlacement(this.
|
|
536
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
474
537
|
Location: params.Position,
|
|
475
538
|
});
|
|
476
539
|
const thickness = params.Thickness ?? 0.05;
|
|
@@ -496,7 +559,7 @@ export class IfcCreator {
|
|
|
496
559
|
* Create a window element. Width × Height × Thickness frame.
|
|
497
560
|
*/
|
|
498
561
|
addIfcWindow(storeyId, params) {
|
|
499
|
-
const placementId = this.addLocalPlacement(this.
|
|
562
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
500
563
|
Location: params.Position,
|
|
501
564
|
});
|
|
502
565
|
const thickness = params.Thickness ?? 0.05;
|
|
@@ -530,7 +593,7 @@ export class IfcCreator {
|
|
|
530
593
|
axis = [Math.sin(slopeAngle), 0, Math.cos(slopeAngle)];
|
|
531
594
|
refDir = [Math.cos(slopeAngle), 0, -Math.sin(slopeAngle)];
|
|
532
595
|
}
|
|
533
|
-
const placementId = this.addLocalPlacement(this.
|
|
596
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
534
597
|
Location: params.Position,
|
|
535
598
|
Axis: axis,
|
|
536
599
|
RefDirection: refDir,
|
|
@@ -561,7 +624,7 @@ export class IfcCreator {
|
|
|
561
624
|
const railLen = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
562
625
|
const dir = vecNorm([dx, dy, dz]);
|
|
563
626
|
// Use identity orientation so posts can extrude vertically along world Z
|
|
564
|
-
const placementId = this.addLocalPlacement(this.
|
|
627
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
565
628
|
Location: params.Start,
|
|
566
629
|
});
|
|
567
630
|
const railWidth = params.Width ?? 0.05;
|
|
@@ -609,7 +672,7 @@ export class IfcCreator {
|
|
|
609
672
|
* Create a plate (thin flat element, e.g. steel plate).
|
|
610
673
|
*/
|
|
611
674
|
addIfcPlate(storeyId, params) {
|
|
612
|
-
const placementId = this.addLocalPlacement(this.
|
|
675
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
613
676
|
Location: params.Position,
|
|
614
677
|
});
|
|
615
678
|
let profileId;
|
|
@@ -643,7 +706,7 @@ export class IfcCreator {
|
|
|
643
706
|
const dz = params.End[2] - params.Start[2];
|
|
644
707
|
const memberLen = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
645
708
|
const dir = vecNorm([dx, dy, dz]);
|
|
646
|
-
const placementId = this.addLocalPlacement(this.
|
|
709
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
647
710
|
Location: params.Start,
|
|
648
711
|
Axis: dir,
|
|
649
712
|
RefDirection: this.computeRefDirection(dir),
|
|
@@ -669,7 +732,7 @@ export class IfcCreator {
|
|
|
669
732
|
*/
|
|
670
733
|
addIfcFooting(storeyId, params) {
|
|
671
734
|
// Offset placement downward so extrusion starts at bottom
|
|
672
|
-
const placementId = this.addLocalPlacement(this.
|
|
735
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
673
736
|
Location: [params.Position[0], params.Position[1], params.Position[2] - params.Height],
|
|
674
737
|
});
|
|
675
738
|
const profileId = this.addRectangleProfile(params.Width, params.Depth);
|
|
@@ -694,7 +757,7 @@ export class IfcCreator {
|
|
|
694
757
|
* Uses circular cross-section by default, rectangular if IsRectangular is set.
|
|
695
758
|
*/
|
|
696
759
|
addIfcPile(storeyId, params) {
|
|
697
|
-
const placementId = this.addLocalPlacement(this.
|
|
760
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
698
761
|
Location: [params.Position[0], params.Position[1], params.Position[2] - params.Length],
|
|
699
762
|
});
|
|
700
763
|
let profileId;
|
|
@@ -724,7 +787,7 @@ export class IfcCreator {
|
|
|
724
787
|
* Create a space (room volume).
|
|
725
788
|
*/
|
|
726
789
|
addIfcSpace(storeyId, params) {
|
|
727
|
-
const placementId = this.addLocalPlacement(this.
|
|
790
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
728
791
|
Location: params.Position,
|
|
729
792
|
});
|
|
730
793
|
let profileId;
|
|
@@ -760,7 +823,7 @@ export class IfcCreator {
|
|
|
760
823
|
const wallLen = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
761
824
|
const dir = vecNorm([dx, dy, dz]);
|
|
762
825
|
const thickness = params.Thickness ?? 0.05;
|
|
763
|
-
const placementId = this.addLocalPlacement(this.
|
|
826
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
764
827
|
Location: params.Start,
|
|
765
828
|
RefDirection: dir,
|
|
766
829
|
});
|
|
@@ -785,7 +848,7 @@ export class IfcCreator {
|
|
|
785
848
|
*/
|
|
786
849
|
addIfcFurnishingElement(storeyId, params) {
|
|
787
850
|
const direction = params.Direction ?? 0;
|
|
788
|
-
const placementId = this.addLocalPlacement(this.
|
|
851
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
789
852
|
Location: params.Position,
|
|
790
853
|
RefDirection: direction !== 0 ? [Math.cos(direction), Math.sin(direction), 0] : undefined,
|
|
791
854
|
});
|
|
@@ -809,7 +872,7 @@ export class IfcCreator {
|
|
|
809
872
|
* Create a proxy element (generic element for custom/unclassified objects).
|
|
810
873
|
*/
|
|
811
874
|
addIfcBuildingElementProxy(storeyId, params) {
|
|
812
|
-
const placementId = this.addLocalPlacement(this.
|
|
875
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
813
876
|
Location: params.Position,
|
|
814
877
|
});
|
|
815
878
|
let profileId;
|
|
@@ -842,7 +905,7 @@ export class IfcCreator {
|
|
|
842
905
|
* Create a column with circular cross-section.
|
|
843
906
|
*/
|
|
844
907
|
addIfcCircularColumn(storeyId, params) {
|
|
845
|
-
const placementId = this.addLocalPlacement(this.
|
|
908
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
846
909
|
Location: params.Position,
|
|
847
910
|
});
|
|
848
911
|
const profileId = this.addCircleProfile(params.Radius);
|
|
@@ -870,7 +933,7 @@ export class IfcCreator {
|
|
|
870
933
|
const dz = params.End[2] - params.Start[2];
|
|
871
934
|
const beamLen = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
872
935
|
const dir = vecNorm([dx, dy, dz]);
|
|
873
|
-
const placementId = this.addLocalPlacement(this.
|
|
936
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
874
937
|
Location: params.Start,
|
|
875
938
|
Axis: dir,
|
|
876
939
|
RefDirection: this.computeRefDirection(dir),
|
|
@@ -900,7 +963,7 @@ export class IfcCreator {
|
|
|
900
963
|
const dz = params.End[2] - params.Start[2];
|
|
901
964
|
const memberLen = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
902
965
|
const dir = vecNorm([dx, dy, dz]);
|
|
903
|
-
const placementId = this.addLocalPlacement(this.
|
|
966
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
904
967
|
Location: params.Start,
|
|
905
968
|
Axis: dir,
|
|
906
969
|
RefDirection: this.computeRefDirection(dir),
|
|
@@ -930,7 +993,7 @@ export class IfcCreator {
|
|
|
930
993
|
const dz = params.End[2] - params.Start[2];
|
|
931
994
|
const memberLen = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
932
995
|
const dir = vecNorm([dx, dy, dz]);
|
|
933
|
-
const placementId = this.addLocalPlacement(this.
|
|
996
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
934
997
|
Location: params.Start,
|
|
935
998
|
Axis: dir,
|
|
936
999
|
RefDirection: this.computeRefDirection(dir),
|
|
@@ -960,7 +1023,7 @@ export class IfcCreator {
|
|
|
960
1023
|
const dz = params.End[2] - params.Start[2];
|
|
961
1024
|
const memberLen = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
962
1025
|
const dir = vecNorm([dx, dy, dz]);
|
|
963
|
-
const placementId = this.addLocalPlacement(this.
|
|
1026
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
964
1027
|
Location: params.Start,
|
|
965
1028
|
Axis: dir,
|
|
966
1029
|
RefDirection: this.computeRefDirection(dir),
|
|
@@ -985,7 +1048,7 @@ export class IfcCreator {
|
|
|
985
1048
|
* Create a column or pile with hollow circular cross-section.
|
|
986
1049
|
*/
|
|
987
1050
|
addIfcHollowCircularColumn(storeyId, params) {
|
|
988
|
-
const placementId = this.addLocalPlacement(this.
|
|
1051
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
989
1052
|
Location: params.Position,
|
|
990
1053
|
});
|
|
991
1054
|
const profileId = this.addCircleHollowProfile(params.Radius, params.WallThickness);
|
|
@@ -1013,7 +1076,7 @@ export class IfcCreator {
|
|
|
1013
1076
|
const dz = params.End[2] - params.Start[2];
|
|
1014
1077
|
const beamLen = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
1015
1078
|
const dir = vecNorm([dx, dy, dz]);
|
|
1016
|
-
const placementId = this.addLocalPlacement(this.
|
|
1079
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
1017
1080
|
Location: params.Start,
|
|
1018
1081
|
Axis: dir,
|
|
1019
1082
|
RefDirection: this.computeRefDirection(dir),
|
|
@@ -1314,7 +1377,7 @@ export class IfcCreator {
|
|
|
1314
1377
|
const desc = optStr(params.Description);
|
|
1315
1378
|
const objType = '$';
|
|
1316
1379
|
const ident = optStr(params.Identification);
|
|
1317
|
-
const creationDate = params.CreationDate ?? new Date().toISOString().slice(0, 19);
|
|
1380
|
+
const creationDate = params.CreationDate ?? new Date(this.nowMs()).toISOString().slice(0, 19);
|
|
1318
1381
|
const purpose = optStr(params.Purpose);
|
|
1319
1382
|
const duration = optStr(params.Duration);
|
|
1320
1383
|
const totalFloat = optStr(params.TotalFloat);
|
|
@@ -1354,7 +1417,7 @@ export class IfcCreator {
|
|
|
1354
1417
|
};
|
|
1355
1418
|
}
|
|
1356
1419
|
buildHeader() {
|
|
1357
|
-
const now = new Date().toISOString().replace(/[-:]/g, '').split('.')[0];
|
|
1420
|
+
const now = new Date(this.nowMs()).toISOString().replace(/[-:]/g, '').split('.')[0];
|
|
1358
1421
|
const desc = 'Created by ifc-lite';
|
|
1359
1422
|
const author = this.projectParams.Author ?? '';
|
|
1360
1423
|
const org = this.projectParams.Organization ?? '';
|
|
@@ -1381,7 +1444,7 @@ ENDSEC;
|
|
|
1381
1444
|
const appId = this.id();
|
|
1382
1445
|
this.line(appId, 'IFCAPPLICATION', `#${orgId},'1.0','ifc-lite','ifc-lite'`);
|
|
1383
1446
|
this.ownerHistoryId = this.id();
|
|
1384
|
-
const timestamp = Math.floor(
|
|
1447
|
+
const timestamp = Math.floor(this.nowMs() / 1000);
|
|
1385
1448
|
this.line(this.ownerHistoryId, 'IFCOWNERHISTORY', `#${personOrgId},#${appId},$,.NOCHANGE.,$,$,$,${timestamp}`);
|
|
1386
1449
|
// Shared geometry primitives
|
|
1387
1450
|
this.originId = this.addCartesianPoint([0, 0, 0]);
|
|
@@ -1812,7 +1875,7 @@ ENDSEC;
|
|
|
1812
1875
|
* ```
|
|
1813
1876
|
*/
|
|
1814
1877
|
addElement(storeyId, params) {
|
|
1815
|
-
const placementId = this.addLocalPlacement(this.
|
|
1878
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), params.Placement);
|
|
1816
1879
|
const profileId = this.createProfile(params.Profile);
|
|
1817
1880
|
// Handle custom extrusion direction
|
|
1818
1881
|
let extrusionDirId;
|
|
@@ -1882,7 +1945,7 @@ ENDSEC;
|
|
|
1882
1945
|
perp = vecCross(dir, [1, 0, 0]);
|
|
1883
1946
|
}
|
|
1884
1947
|
perp = vecNorm(perp);
|
|
1885
|
-
const placementId = this.addLocalPlacement(this.
|
|
1948
|
+
const placementId = this.addLocalPlacement(this.getStoreyPlacement(storeyId), {
|
|
1886
1949
|
Location: params.Start,
|
|
1887
1950
|
Axis: dir, // local Z = along axis (extrusion direction)
|
|
1888
1951
|
RefDirection: perp, // local X = perpendicular to axis
|