brepjs-bim 0.14.0 → 0.15.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 CHANGED
@@ -67,15 +67,16 @@ Author a small model and export IFC:
67
67
 
68
68
  ```ts
69
69
  import { BimModel, toIfc } from 'brepjs-bim';
70
+ import { unwrap } from 'brepjs';
70
71
 
71
72
  const model = new BimModel();
72
73
  model.init({ name: 'Example' });
73
74
 
74
75
  // Spatial structure: project → site → building → storey.
75
76
  const project = model.getProject();
76
- const siteId = model.addSite({ name: 'Site' });
77
- const buildingId = model.addBuilding({ name: 'Building' });
78
- const storeyId = model.addStorey({ name: 'Level 1', elevation: 0 });
77
+ const siteId = unwrap(model.addSite({ name: 'Site' }));
78
+ const buildingId = unwrap(model.addBuilding({ name: 'Building' }));
79
+ const storeyId = unwrap(model.addStorey({ name: 'Level 1', elevation: 0 }));
79
80
  if (project) model.aggregate(project.localId, siteId);
80
81
  model.aggregate(siteId, buildingId);
81
82
  model.aggregate(buildingId, storeyId);
@@ -6334,14 +6334,20 @@ var BimModel = class {
6334
6334
  for (const mullion of el.geometry.mullions) mullion.solid[Symbol.dispose]();
6335
6335
  }
6336
6336
  }
6337
- addSite(spec) {
6338
- return this.#makeElement("SITE", spec, null);
6337
+ addSite(spec, options) {
6338
+ const keyCheck = this.#checkStableKey(options);
6339
+ if (!keyCheck.ok) return keyCheck;
6340
+ return (0, brepjs.ok)(this.#makeElement("SITE", spec, null, options?.stableKey));
6339
6341
  }
6340
6342
  addBuilding(spec, options) {
6341
- return this.#makeElement("BUILDING", spec, null, options?.stableKey);
6343
+ const keyCheck = this.#checkStableKey(options);
6344
+ if (!keyCheck.ok) return keyCheck;
6345
+ return (0, brepjs.ok)(this.#makeElement("BUILDING", spec, null, options?.stableKey));
6342
6346
  }
6343
6347
  addStorey(spec, options) {
6344
- return this.#makeElement("STOREY", spec, null, options?.stableKey);
6348
+ const keyCheck = this.#checkStableKey(options);
6349
+ if (!keyCheck.ok) return keyCheck;
6350
+ return (0, brepjs.ok)(this.#makeElement("STOREY", spec, null, options?.stableKey));
6345
6351
  }
6346
6352
  /** Reject a duplicate stableKey BEFORE any geometry is built, so the
6347
6353
  * Result-returning adders never allocate a solid they cannot store. */
@@ -6508,24 +6514,30 @@ var BimModel = class {
6508
6514
  * attach parts with {@link aggregate} (IfcRelAggregates) or {@link nest}
6509
6515
  * (IfcRelNests, order-preserving). Returns the assembly's localId.
6510
6516
  */
6511
- addElementAssembly(spec) {
6512
- return this.#makeElement("ELEMENT_ASSEMBLY", spec, null);
6517
+ addElementAssembly(spec, options) {
6518
+ const keyCheck = this.#checkStableKey(options);
6519
+ if (!keyCheck.ok) return keyCheck;
6520
+ return (0, brepjs.ok)(this.#makeElement("ELEMENT_ASSEMBLY", spec, null, options?.stableKey));
6513
6521
  }
6514
6522
  /**
6515
6523
  * Adds an IfcZone grouping object (a thermal/fire/occupancy zone). The zone
6516
6524
  * carries no geometry; attach members (spaces or other elements) with
6517
- * {@link assignToGroup}. Returns the zone's localId.
6525
+ * {@link assignToGroup}. Returns the zone's localId as a Result.
6518
6526
  */
6519
- addZone(spec) {
6520
- return this.#makeElement("ZONE", spec, null);
6527
+ addZone(spec, options) {
6528
+ const keyCheck = this.#checkStableKey(options);
6529
+ if (!keyCheck.ok) return keyCheck;
6530
+ return (0, brepjs.ok)(this.#makeElement("ZONE", spec, null, options?.stableKey));
6521
6531
  }
6522
6532
  /**
6523
6533
  * Adds an IfcSystem grouping object (an HVAC/electrical/plumbing system). The
6524
6534
  * system carries no geometry; attach members with {@link assignToGroup}.
6525
- * Returns the system's localId.
6535
+ * Returns the system's localId as a Result.
6526
6536
  */
6527
- addSystem(spec) {
6528
- return this.#makeElement("SYSTEM", spec, null);
6537
+ addSystem(spec, options) {
6538
+ const keyCheck = this.#checkStableKey(options);
6539
+ if (!keyCheck.ok) return keyCheck;
6540
+ return (0, brepjs.ok)(this.#makeElement("SYSTEM", spec, null, options?.stableKey));
6529
6541
  }
6530
6542
  /**
6531
6543
  * Assigns members to a zone or system via IfcRelAssignsToGroup. Repeated calls
@@ -16747,9 +16759,18 @@ function familiesToBim(root, options) {
16747
16759
  const model = new BimModel();
16748
16760
  const initResult = model.init(options.project);
16749
16761
  if (!initResult.ok) return initResult;
16750
- const siteId = model.addSite({ name: options.siteName ?? "Site" });
16751
- const buildingId = model.addBuilding({ name: options.buildingName ?? "Building" });
16752
- model.aggregate(siteId, buildingId);
16762
+ const siteResult = model.addSite({ name: options.siteName ?? "Site" });
16763
+ if (!siteResult.ok) {
16764
+ model[Symbol.dispose]();
16765
+ return siteResult;
16766
+ }
16767
+ const buildingResult = model.addBuilding({ name: options.buildingName ?? "Building" });
16768
+ if (!buildingResult.ok) {
16769
+ model[Symbol.dispose]();
16770
+ return buildingResult;
16771
+ }
16772
+ const buildingId = buildingResult.value;
16773
+ model.aggregate(siteResult.value, buildingId);
16753
16774
  const idByKeyPath = /* @__PURE__ */ new Map();
16754
16775
  const walk = (el, storeyId) => {
16755
16776
  let containerId = storeyId;
@@ -16757,13 +16778,14 @@ function familiesToBim(root, options) {
16757
16778
  if (el.type === "Storey") {
16758
16779
  const keyed = requireKeyed(el);
16759
16780
  if (!keyed.ok) return keyed;
16760
- const id = model.addStorey({
16781
+ const storeyResult = model.addStorey({
16761
16782
  name: el.attributes["name"] ?? el.keyPath,
16762
16783
  elevation: el.props["elevation"] ?? 0
16763
16784
  }, { stableKey: el.keyPath });
16764
- model.aggregate(buildingId, id);
16765
- idByKeyPath.set(el.keyPath, id);
16766
- containerId = id;
16785
+ if (!storeyResult.ok) return storeyResult;
16786
+ model.aggregate(buildingId, storeyResult.value);
16787
+ idByKeyPath.set(el.keyPath, storeyResult.value);
16788
+ containerId = storeyResult.value;
16767
16789
  } else if (route !== void 0) {
16768
16790
  const keyed = requireKeyed(el);
16769
16791
  if (!keyed.ok) return keyed;
@@ -6311,14 +6311,20 @@ var BimModel = class {
6311
6311
  for (const mullion of el.geometry.mullions) mullion.solid[Symbol.dispose]();
6312
6312
  }
6313
6313
  }
6314
- addSite(spec) {
6315
- return this.#makeElement("SITE", spec, null);
6314
+ addSite(spec, options) {
6315
+ const keyCheck = this.#checkStableKey(options);
6316
+ if (!keyCheck.ok) return keyCheck;
6317
+ return ok(this.#makeElement("SITE", spec, null, options?.stableKey));
6316
6318
  }
6317
6319
  addBuilding(spec, options) {
6318
- return this.#makeElement("BUILDING", spec, null, options?.stableKey);
6320
+ const keyCheck = this.#checkStableKey(options);
6321
+ if (!keyCheck.ok) return keyCheck;
6322
+ return ok(this.#makeElement("BUILDING", spec, null, options?.stableKey));
6319
6323
  }
6320
6324
  addStorey(spec, options) {
6321
- return this.#makeElement("STOREY", spec, null, options?.stableKey);
6325
+ const keyCheck = this.#checkStableKey(options);
6326
+ if (!keyCheck.ok) return keyCheck;
6327
+ return ok(this.#makeElement("STOREY", spec, null, options?.stableKey));
6322
6328
  }
6323
6329
  /** Reject a duplicate stableKey BEFORE any geometry is built, so the
6324
6330
  * Result-returning adders never allocate a solid they cannot store. */
@@ -6485,24 +6491,30 @@ var BimModel = class {
6485
6491
  * attach parts with {@link aggregate} (IfcRelAggregates) or {@link nest}
6486
6492
  * (IfcRelNests, order-preserving). Returns the assembly's localId.
6487
6493
  */
6488
- addElementAssembly(spec) {
6489
- return this.#makeElement("ELEMENT_ASSEMBLY", spec, null);
6494
+ addElementAssembly(spec, options) {
6495
+ const keyCheck = this.#checkStableKey(options);
6496
+ if (!keyCheck.ok) return keyCheck;
6497
+ return ok(this.#makeElement("ELEMENT_ASSEMBLY", spec, null, options?.stableKey));
6490
6498
  }
6491
6499
  /**
6492
6500
  * Adds an IfcZone grouping object (a thermal/fire/occupancy zone). The zone
6493
6501
  * carries no geometry; attach members (spaces or other elements) with
6494
- * {@link assignToGroup}. Returns the zone's localId.
6502
+ * {@link assignToGroup}. Returns the zone's localId as a Result.
6495
6503
  */
6496
- addZone(spec) {
6497
- return this.#makeElement("ZONE", spec, null);
6504
+ addZone(spec, options) {
6505
+ const keyCheck = this.#checkStableKey(options);
6506
+ if (!keyCheck.ok) return keyCheck;
6507
+ return ok(this.#makeElement("ZONE", spec, null, options?.stableKey));
6498
6508
  }
6499
6509
  /**
6500
6510
  * Adds an IfcSystem grouping object (an HVAC/electrical/plumbing system). The
6501
6511
  * system carries no geometry; attach members with {@link assignToGroup}.
6502
- * Returns the system's localId.
6512
+ * Returns the system's localId as a Result.
6503
6513
  */
6504
- addSystem(spec) {
6505
- return this.#makeElement("SYSTEM", spec, null);
6514
+ addSystem(spec, options) {
6515
+ const keyCheck = this.#checkStableKey(options);
6516
+ if (!keyCheck.ok) return keyCheck;
6517
+ return ok(this.#makeElement("SYSTEM", spec, null, options?.stableKey));
6506
6518
  }
6507
6519
  /**
6508
6520
  * Assigns members to a zone or system via IfcRelAssignsToGroup. Repeated calls
@@ -16724,9 +16736,18 @@ function familiesToBim(root, options) {
16724
16736
  const model = new BimModel();
16725
16737
  const initResult = model.init(options.project);
16726
16738
  if (!initResult.ok) return initResult;
16727
- const siteId = model.addSite({ name: options.siteName ?? "Site" });
16728
- const buildingId = model.addBuilding({ name: options.buildingName ?? "Building" });
16729
- model.aggregate(siteId, buildingId);
16739
+ const siteResult = model.addSite({ name: options.siteName ?? "Site" });
16740
+ if (!siteResult.ok) {
16741
+ model[Symbol.dispose]();
16742
+ return siteResult;
16743
+ }
16744
+ const buildingResult = model.addBuilding({ name: options.buildingName ?? "Building" });
16745
+ if (!buildingResult.ok) {
16746
+ model[Symbol.dispose]();
16747
+ return buildingResult;
16748
+ }
16749
+ const buildingId = buildingResult.value;
16750
+ model.aggregate(siteResult.value, buildingId);
16730
16751
  const idByKeyPath = /* @__PURE__ */ new Map();
16731
16752
  const walk = (el, storeyId) => {
16732
16753
  let containerId = storeyId;
@@ -16734,13 +16755,14 @@ function familiesToBim(root, options) {
16734
16755
  if (el.type === "Storey") {
16735
16756
  const keyed = requireKeyed(el);
16736
16757
  if (!keyed.ok) return keyed;
16737
- const id = model.addStorey({
16758
+ const storeyResult = model.addStorey({
16738
16759
  name: el.attributes["name"] ?? el.keyPath,
16739
16760
  elevation: el.props["elevation"] ?? 0
16740
16761
  }, { stableKey: el.keyPath });
16741
- model.aggregate(buildingId, id);
16742
- idByKeyPath.set(el.keyPath, id);
16743
- containerId = id;
16762
+ if (!storeyResult.ok) return storeyResult;
16763
+ model.aggregate(buildingId, storeyResult.value);
16764
+ idByKeyPath.set(el.keyPath, storeyResult.value);
16765
+ containerId = storeyResult.value;
16744
16766
  } else if (route !== void 0) {
16745
16767
  const keyed = requireKeyed(el);
16746
16768
  if (!keyed.ok) return keyed;
@@ -37,9 +37,9 @@ export declare class BimModel {
37
37
  #private;
38
38
  init(spec: ProjectSpec): Result<LocalId, BimError>;
39
39
  [Symbol.dispose](): void;
40
- addSite(spec: SiteSpec): LocalId;
41
- addBuilding(spec: BuildingSpec, options?: ElementIdentityOptions): LocalId;
42
- addStorey(spec: StoreySpec, options?: ElementIdentityOptions): LocalId;
40
+ addSite(spec: SiteSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
41
+ addBuilding(spec: BuildingSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
42
+ addStorey(spec: StoreySpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
43
43
  addWall(spec: WallSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
44
44
  addSlab(spec: SlabSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
45
45
  addBeam(spec: BeamSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
@@ -72,19 +72,19 @@ export declare class BimModel {
72
72
  * attach parts with {@link aggregate} (IfcRelAggregates) or {@link nest}
73
73
  * (IfcRelNests, order-preserving). Returns the assembly's localId.
74
74
  */
75
- addElementAssembly(spec: ElementAssemblySpec): LocalId;
75
+ addElementAssembly(spec: ElementAssemblySpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
76
76
  /**
77
77
  * Adds an IfcZone grouping object (a thermal/fire/occupancy zone). The zone
78
78
  * carries no geometry; attach members (spaces or other elements) with
79
- * {@link assignToGroup}. Returns the zone's localId.
79
+ * {@link assignToGroup}. Returns the zone's localId as a Result.
80
80
  */
81
- addZone(spec: ZoneSpec): LocalId;
81
+ addZone(spec: ZoneSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
82
82
  /**
83
83
  * Adds an IfcSystem grouping object (an HVAC/electrical/plumbing system). The
84
84
  * system carries no geometry; attach members with {@link assignToGroup}.
85
- * Returns the system's localId.
85
+ * Returns the system's localId as a Result.
86
86
  */
87
- addSystem(spec: SystemSpec): LocalId;
87
+ addSystem(spec: SystemSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
88
88
  /**
89
89
  * Assigns members to a zone or system via IfcRelAssignsToGroup. Repeated calls
90
90
  * for the same group extend the single relationship in call order. Returns the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brepjs-bim",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "BIM layer for brepjs — IFC4-aligned parametric building elements",
5
5
  "keywords": [
6
6
  "bim",