@bitbybit-dev/ifc 0.0.0-stage → 1.5.0-rc.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.
Files changed (242) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +42 -0
  3. package/README.md +92 -2
  4. package/index.d.ts +1 -0
  5. package/index.js +1 -0
  6. package/lib/api/dto-registry.d.ts +8 -0
  7. package/lib/api/dto-registry.js +109 -0
  8. package/lib/api/ifc-service.d.ts +109 -0
  9. package/lib/api/ifc-service.js +55 -0
  10. package/lib/api/inputs/base-inputs.d.ts +5 -0
  11. package/lib/api/inputs/base-inputs.js +5 -0
  12. package/lib/api/inputs/ifc-inputs.d.ts +2727 -0
  13. package/lib/api/inputs/ifc-inputs.js +2498 -0
  14. package/lib/api/inputs/index.d.ts +3 -0
  15. package/lib/api/inputs/index.js +3 -0
  16. package/lib/api/resolved-inputs/index.d.ts +70 -0
  17. package/lib/api/resolved-inputs/index.js +1 -0
  18. package/lib/api/services/assemblies.d.ts +28 -0
  19. package/lib/api/services/assemblies.js +49 -0
  20. package/lib/api/services/beams.d.ts +33 -0
  21. package/lib/api/services/beams.js +59 -0
  22. package/lib/api/services/columns.d.ts +26 -0
  23. package/lib/api/services/columns.js +56 -0
  24. package/lib/api/services/defaults.constants.d.ts +44 -0
  25. package/lib/api/services/defaults.constants.js +44 -0
  26. package/lib/api/services/doors.d.ts +45 -0
  27. package/lib/api/services/doors.js +94 -0
  28. package/lib/api/services/geometry.d.ts +51 -0
  29. package/lib/api/services/geometry.js +87 -0
  30. package/lib/api/services/index.d.ts +17 -0
  31. package/lib/api/services/index.js +17 -0
  32. package/lib/api/services/materials.d.ts +46 -0
  33. package/lib/api/services/materials.js +86 -0
  34. package/lib/api/services/member-support.d.ts +7 -0
  35. package/lib/api/services/member-support.js +29 -0
  36. package/lib/api/services/members.d.ts +24 -0
  37. package/lib/api/services/members.js +51 -0
  38. package/lib/api/services/model.d.ts +244 -0
  39. package/lib/api/services/model.js +409 -0
  40. package/lib/api/services/openings.d.ts +57 -0
  41. package/lib/api/services/openings.js +102 -0
  42. package/lib/api/services/properties.d.ts +89 -0
  43. package/lib/api/services/properties.js +142 -0
  44. package/lib/api/services/quantities.d.ts +38 -0
  45. package/lib/api/services/quantities.js +51 -0
  46. package/lib/api/services/roofs.d.ts +24 -0
  47. package/lib/api/services/roofs.js +52 -0
  48. package/lib/api/services/service-support.d.ts +8 -0
  49. package/lib/api/services/service-support.js +37 -0
  50. package/lib/api/services/service-types.d.ts +3 -0
  51. package/lib/api/services/service-types.js +1 -0
  52. package/lib/api/services/site.d.ts +37 -0
  53. package/lib/api/services/site.js +80 -0
  54. package/lib/api/services/slabs.d.ts +31 -0
  55. package/lib/api/services/slabs.js +59 -0
  56. package/lib/api/services/spaces.d.ts +36 -0
  57. package/lib/api/services/spaces.js +64 -0
  58. package/lib/api/services/spatial.d.ts +54 -0
  59. package/lib/api/services/spatial.js +75 -0
  60. package/lib/api/services/walls.d.ts +140 -0
  61. package/lib/api/services/walls.js +268 -0
  62. package/lib/api/services/windows.d.ts +46 -0
  63. package/lib/api/services/windows.js +76 -0
  64. package/lib/build/assemblies.d.ts +4 -0
  65. package/lib/build/assemblies.js +45 -0
  66. package/lib/build/build-types.d.ts +345 -0
  67. package/lib/build/build-types.js +1 -0
  68. package/lib/build/checks.d.ts +6 -0
  69. package/lib/build/checks.js +32 -0
  70. package/lib/build/constants.d.ts +27 -0
  71. package/lib/build/constants.js +43 -0
  72. package/lib/build/contexts.d.ts +9 -0
  73. package/lib/build/contexts.js +52 -0
  74. package/lib/build/curves.d.ts +3 -0
  75. package/lib/build/curves.js +23 -0
  76. package/lib/build/entity-writer.d.ts +23 -0
  77. package/lib/build/entity-writer.js +97 -0
  78. package/lib/build/fillings.d.ts +7 -0
  79. package/lib/build/fillings.js +182 -0
  80. package/lib/build/georeference.d.ts +5 -0
  81. package/lib/build/georeference.js +44 -0
  82. package/lib/build/materials.d.ts +18 -0
  83. package/lib/build/materials.js +166 -0
  84. package/lib/build/math.d.ts +10 -0
  85. package/lib/build/math.js +47 -0
  86. package/lib/build/measure.d.ts +9 -0
  87. package/lib/build/measure.js +195 -0
  88. package/lib/build/moving.d.ts +4 -0
  89. package/lib/build/moving.js +61 -0
  90. package/lib/build/openings.d.ts +12 -0
  91. package/lib/build/openings.js +156 -0
  92. package/lib/build/outlines.d.ts +4 -0
  93. package/lib/build/outlines.js +40 -0
  94. package/lib/build/placement.d.ts +16 -0
  95. package/lib/build/placement.js +106 -0
  96. package/lib/build/profiles.d.ts +4 -0
  97. package/lib/build/profiles.js +35 -0
  98. package/lib/build/project.d.ts +11 -0
  99. package/lib/build/project.js +134 -0
  100. package/lib/build/properties.d.ts +10 -0
  101. package/lib/build/properties.js +182 -0
  102. package/lib/build/quantities.d.ts +7 -0
  103. package/lib/build/quantities.js +262 -0
  104. package/lib/build/relationships.d.ts +9 -0
  105. package/lib/build/relationships.js +67 -0
  106. package/lib/build/removal.d.ts +3 -0
  107. package/lib/build/removal.js +106 -0
  108. package/lib/build/representations.d.ts +6 -0
  109. package/lib/build/representations.js +46 -0
  110. package/lib/build/roof-clipping.d.ts +5 -0
  111. package/lib/build/roof-clipping.js +79 -0
  112. package/lib/build/roofs.d.ts +4 -0
  113. package/lib/build/roofs.js +131 -0
  114. package/lib/build/site.d.ts +7 -0
  115. package/lib/build/site.js +112 -0
  116. package/lib/build/slab-openings.d.ts +4 -0
  117. package/lib/build/slab-openings.js +71 -0
  118. package/lib/build/slabs-columns-beams.d.ts +8 -0
  119. package/lib/build/slabs-columns-beams.js +73 -0
  120. package/lib/build/solids.d.ts +5 -0
  121. package/lib/build/solids.js +33 -0
  122. package/lib/build/spaces.d.ts +6 -0
  123. package/lib/build/spaces.js +55 -0
  124. package/lib/build/spatial.d.ts +17 -0
  125. package/lib/build/spatial.js +111 -0
  126. package/lib/build/type-objects.d.ts +4 -0
  127. package/lib/build/type-objects.js +9 -0
  128. package/lib/build/wall-edits.d.ts +5 -0
  129. package/lib/build/wall-edits.js +138 -0
  130. package/lib/build/wall-geometry.d.ts +15 -0
  131. package/lib/build/wall-geometry.js +159 -0
  132. package/lib/build/wall-parameters.d.ts +3 -0
  133. package/lib/build/wall-parameters.js +47 -0
  134. package/lib/build/walls.d.ts +12 -0
  135. package/lib/build/walls.js +238 -0
  136. package/lib/geometry/advanced.d.ts +27 -0
  137. package/lib/geometry/advanced.js +292 -0
  138. package/lib/geometry/colours.d.ts +3 -0
  139. package/lib/geometry/colours.js +109 -0
  140. package/lib/geometry/curves.d.ts +32 -0
  141. package/lib/geometry/curves.js +370 -0
  142. package/lib/geometry/edges.constants.d.ts +5 -0
  143. package/lib/geometry/edges.constants.js +5 -0
  144. package/lib/geometry/edges.d.ts +21 -0
  145. package/lib/geometry/edges.js +164 -0
  146. package/lib/geometry/elements.d.ts +3 -0
  147. package/lib/geometry/elements.js +152 -0
  148. package/lib/geometry/errors.d.ts +3 -0
  149. package/lib/geometry/errors.js +6 -0
  150. package/lib/geometry/faceted.d.ts +31 -0
  151. package/lib/geometry/faceted.js +214 -0
  152. package/lib/geometry/geometry-types.d.ts +103 -0
  153. package/lib/geometry/geometry-types.js +1 -0
  154. package/lib/geometry/groups.d.ts +21 -0
  155. package/lib/geometry/groups.js +106 -0
  156. package/lib/geometry/items.d.ts +34 -0
  157. package/lib/geometry/items.js +313 -0
  158. package/lib/geometry/operators.d.ts +3 -0
  159. package/lib/geometry/operators.js +65 -0
  160. package/lib/geometry/profiles.d.ts +4 -0
  161. package/lib/geometry/profiles.js +277 -0
  162. package/lib/geometry/recipe-builder.d.ts +14 -0
  163. package/lib/geometry/recipe-builder.js +48 -0
  164. package/lib/geometry/references.d.ts +4 -0
  165. package/lib/geometry/references.js +17 -0
  166. package/lib/geometry/regions.d.ts +4 -0
  167. package/lib/geometry/regions.js +26 -0
  168. package/lib/geometry/surfaces.constants.d.ts +17 -0
  169. package/lib/geometry/surfaces.constants.js +17 -0
  170. package/lib/geometry/surfaces.d.ts +6 -0
  171. package/lib/geometry/surfaces.js +306 -0
  172. package/lib/geometry/swept-solids.constants.d.ts +7 -0
  173. package/lib/geometry/swept-solids.constants.js +6 -0
  174. package/lib/geometry/swept-solids.d.ts +25 -0
  175. package/lib/geometry/swept-solids.js +243 -0
  176. package/lib/index.d.ts +6 -0
  177. package/lib/index.js +6 -0
  178. package/lib/model/constants.d.ts +30 -0
  179. package/lib/model/constants.js +30 -0
  180. package/lib/model/entity-lookup.d.ts +9 -0
  181. package/lib/model/entity-lookup.js +20 -0
  182. package/lib/model/guid.d.ts +7 -0
  183. package/lib/model/guid.js +60 -0
  184. package/lib/model/id-map.d.ts +10 -0
  185. package/lib/model/id-map.js +80 -0
  186. package/lib/model/index.d.ts +4 -0
  187. package/lib/model/index.js +2 -0
  188. package/lib/model/io.d.ts +6 -0
  189. package/lib/model/io.js +136 -0
  190. package/lib/model/is-model.d.ts +9 -0
  191. package/lib/model/is-model.js +11 -0
  192. package/lib/model/model-types.d.ts +111 -0
  193. package/lib/model/model-types.js +1 -0
  194. package/lib/model/overlay-indexes.d.ts +17 -0
  195. package/lib/model/overlay-indexes.js +69 -0
  196. package/lib/model/references.d.ts +2 -0
  197. package/lib/model/references.js +51 -0
  198. package/lib/model/rows-by-id.d.ts +8 -0
  199. package/lib/model/rows-by-id.js +39 -0
  200. package/lib/model/snapshot.d.ts +36 -0
  201. package/lib/model/snapshot.js +144 -0
  202. package/lib/model/source.d.ts +29 -0
  203. package/lib/model/source.js +172 -0
  204. package/lib/model/transaction.d.ts +39 -0
  205. package/lib/model/transaction.js +250 -0
  206. package/lib/model/upgrade.d.ts +2 -0
  207. package/lib/model/upgrade.js +78 -0
  208. package/lib/schema/constants.d.ts +3 -0
  209. package/lib/schema/constants.js +3 -0
  210. package/lib/schema/generated/ifc4.d.ts +2 -0
  211. package/lib/schema/generated/ifc4.js +1204 -0
  212. package/lib/schema/generated/ifc4x3.d.ts +2 -0
  213. package/lib/schema/generated/ifc4x3.js +1325 -0
  214. package/lib/schema/registry.d.ts +7 -0
  215. package/lib/schema/registry.js +37 -0
  216. package/lib/schema/schema-types.d.ts +45 -0
  217. package/lib/schema/schema-types.js +1 -0
  218. package/lib/schema/schema.d.ts +23 -0
  219. package/lib/schema/schema.js +136 -0
  220. package/lib/step/constants.d.ts +48 -0
  221. package/lib/step/constants.js +48 -0
  222. package/lib/step/encoder.d.ts +21 -0
  223. package/lib/step/encoder.js +321 -0
  224. package/lib/step/errors.d.ts +39 -0
  225. package/lib/step/errors.js +45 -0
  226. package/lib/step/file-index.d.ts +2 -0
  227. package/lib/step/file-index.js +221 -0
  228. package/lib/step/header.d.ts +4 -0
  229. package/lib/step/header.js +52 -0
  230. package/lib/step/numbers.d.ts +3 -0
  231. package/lib/step/numbers.js +73 -0
  232. package/lib/step/reader.d.ts +2 -0
  233. package/lib/step/reader.js +160 -0
  234. package/lib/step/scanner.d.ts +13 -0
  235. package/lib/step/scanner.js +203 -0
  236. package/lib/step/step-types.d.ts +170 -0
  237. package/lib/step/step-types.js +1 -0
  238. package/lib/step/strings.d.ts +2 -0
  239. package/lib/step/strings.js +150 -0
  240. package/lib/step/values.d.ts +13 -0
  241. package/lib/step/values.js +51 -0
  242. package/package.json +51 -5
@@ -0,0 +1,76 @@
1
+ import { resolveDto } from "@bitbybit-dev/base";
2
+ import { createFilling, createWindowType } from "../../build/fillings";
3
+ import * as Inputs from "../inputs";
4
+ import { DEFAULT_MILLIMETRES } from "./defaults.constants";
5
+ import { editModel, lengthIn, lengthTolerance, modelOf, resolveId } from "./service-support";
6
+ /**
7
+ * Windows: window types, each a frame around one pane of glass, and windows of those types placed
8
+ * in walls. A window cuts its own opening and shares its type's geometry, so a type placed many
9
+ * times is written once.
10
+ * @beta
11
+ */
12
+ export class IFCWindows {
13
+ /**
14
+ * Adds a window type: a frame around one pane, `width` by `height`, which windows are then
15
+ * placed from.
16
+ *
17
+ * The frame's members are `frameThickness` wide and `frameDepth` deep; the glass sits in the
18
+ * middle of the depth. A `frameMaterial` and a `glassMaterial` give each part its material and
19
+ * colour.
20
+ * @param inputs - The model, the type's id and name, and its sizes
21
+ * @returns A new model with the window type
22
+ * @group types
23
+ * @shortname add window type
24
+ * @drawable false
25
+ * @example
26
+ * ```typescript
27
+ * model = await bitbybit.ifc.materials.add({ model, name: "Glass", color: "#a9c7d6", transparency: 0.7 });
28
+ * model = await bitbybit.ifc.windows.addType({ model, id: "window-120", name: "Window 1200", width: 1200, height: 1400, glassMaterial: "Glass" });
29
+ * ```
30
+ */
31
+ addType(inputs) {
32
+ const resolved = resolveDto(Inputs.IFC.AddWindowTypeDto, inputs);
33
+ const model = modelOf(resolved.model);
34
+ const spec = {
35
+ id: resolved.id,
36
+ name: resolved.name,
37
+ width: lengthIn(model, resolved.width, DEFAULT_MILLIMETRES.windowWidth),
38
+ height: lengthIn(model, resolved.height, DEFAULT_MILLIMETRES.windowHeight),
39
+ frameThickness: lengthIn(model, resolved.frameThickness, DEFAULT_MILLIMETRES.frameThickness),
40
+ frameDepth: lengthIn(model, resolved.frameDepth, DEFAULT_MILLIMETRES.frameDepth),
41
+ glassThickness: lengthIn(model, resolved.glassThickness, DEFAULT_MILLIMETRES.glassThickness),
42
+ frameMaterial: resolved.frameMaterial,
43
+ glassMaterial: resolved.glassMaterial,
44
+ };
45
+ return editModel(model, (tx, writer) => {
46
+ createWindowType(tx, writer, spec);
47
+ });
48
+ }
49
+ /**
50
+ * Places a window of a window type in a wall, `offset` along the wall's axis from its start and
51
+ * `sill` above its base, cutting an opening as wide and high as the type.
52
+ *
53
+ * The window is centred in the wall's thickness and belongs to the wall's storey. It must fit
54
+ * along the wall.
55
+ * @param inputs - The model, the wall, the window type, and where the window goes
56
+ * @returns A new model with the window
57
+ * @group create
58
+ * @shortname add window
59
+ * @drawable false
60
+ * @example
61
+ * ```typescript
62
+ * model = await bitbybit.ifc.windows.add({ model, wall: "south", windowType: "window-120", offset: 6000, sill: 900 });
63
+ * ```
64
+ */
65
+ add(inputs) {
66
+ const resolved = resolveDto(Inputs.IFC.AddWindowDto, inputs);
67
+ const model = modelOf(resolved.model);
68
+ const wall = resolveId(model, resolved.wall, "IfcWall", "wall");
69
+ const type = resolveId(model, resolved.windowType, "IfcWindowType", "window type");
70
+ return editModel(model, (tx, writer) => {
71
+ const offset = lengthIn(model, resolved.offset, DEFAULT_MILLIMETRES.openingOffset);
72
+ const sill = lengthIn(model, resolved.sill, DEFAULT_MILLIMETRES.windowSill);
73
+ createFilling(tx, writer, "IfcWindow", { wall, type, id: resolved.id, name: resolved.name, offset, sill }, lengthTolerance(model));
74
+ });
75
+ }
76
+ }
@@ -0,0 +1,4 @@
1
+ import type { IfcTransaction } from "../model/transaction";
2
+ import type { EntityWriter } from "./entity-writer";
3
+ import type { AssemblySpec } from "./build-types";
4
+ export declare function createAssembly(tx: IfcTransaction, writer: EntityWriter, spec: AssemblySpec): number;
@@ -0,0 +1,45 @@
1
+ import { WORLD_AXES } from "@bitbybit-dev/base/lib/api/services/helpers/frame-axes";
2
+ import { enumValue, ref } from "../step/values";
3
+ import { AGGREGATION, CONTAINMENT } from "./constants";
4
+ import { objectPlacementOf } from "./placement";
5
+ import { detach, relate, relatingOf } from "./relationships";
6
+ import { containIn, containerOf, describeObject } from "./spatial";
7
+ const FEATURE_ELEMENT = "IfcFeatureElement";
8
+ function containerOfParts(tx, parts) {
9
+ const containers = new Set();
10
+ for (const part of parts) {
11
+ if (tx.schema.isSubtypeOf(tx.entity(part).type, FEATURE_ELEMENT)) {
12
+ throw new Error(`${describeObject(tx, part)} cuts or adds to another element, so it cannot be part of an assembly`);
13
+ }
14
+ const whole = relatingOf(tx, AGGREGATION, part);
15
+ if (whole !== undefined) {
16
+ throw new Error(`${describeObject(tx, part)} is already part of ${describeObject(tx, whole)}`);
17
+ }
18
+ const container = containerOf(tx, part);
19
+ if (container === undefined) {
20
+ throw new Error(`${describeObject(tx, part)} stands in no storey or other part of the structure, so an assembly of it has nowhere to stand`);
21
+ }
22
+ containers.add(container);
23
+ }
24
+ if (containers.size !== 1) {
25
+ throw new Error(`The parts stand in ${containers.size} parts of the structure; an assembly stands in one`);
26
+ }
27
+ return [...containers][0];
28
+ }
29
+ export function createAssembly(tx, writer, spec) {
30
+ var _a, _b;
31
+ const container = containerOfParts(tx, spec.parts);
32
+ const assembly = writer.create("IfcElementAssembly", {
33
+ GlobalId: tx.globalId(spec.id),
34
+ Name: (_a = spec.name) !== null && _a !== void 0 ? _a : null,
35
+ ObjectType: (_b = spec.objectType) !== null && _b !== void 0 ? _b : null,
36
+ ObjectPlacement: ref(writer.localPlacement(objectPlacementOf(tx, container), WORLD_AXES)),
37
+ PredefinedType: enumValue(spec.predefinedType),
38
+ });
39
+ for (const part of spec.parts) {
40
+ detach(tx, CONTAINMENT, part);
41
+ }
42
+ containIn(tx, writer, container, assembly);
43
+ relate(tx, writer, AGGREGATION, assembly, spec.parts);
44
+ return assembly;
45
+ }
@@ -0,0 +1,345 @@
1
+ import type { Base } from "@bitbybit-dev/base";
2
+ import type { MeshArrays } from "@bitbybit-dev/base/lib/api/services/helpers/helper-types";
3
+ import type { FrameAxes } from "@bitbybit-dev/base/lib/api/services/helpers/frame-axes";
4
+ import type * as Inputs from "../api/inputs";
5
+ import type { IfcSchema } from "../schema/schema";
6
+ import type { IfcEntity, IfcFileHeader, IfcValue } from "../step/step-types";
7
+ export type Frame3 = FrameAxes;
8
+ export interface Line2 {
9
+ readonly point: Base.Point2;
10
+ readonly direction: Base.Vector2;
11
+ }
12
+ export interface EntityReader {
13
+ entity(id: number): IfcEntity;
14
+ attribute(id: number, name: string): IfcValue;
15
+ }
16
+ export interface ModelReader extends EntityReader {
17
+ readonly schema: IfcSchema;
18
+ get(id: number): IfcEntity | undefined;
19
+ typeOf(id: number): string | undefined;
20
+ byType(type: string): IfcEntity[];
21
+ referencesTo(id: number): readonly number[];
22
+ }
23
+ export interface RelationshipRoles {
24
+ readonly relationship: string;
25
+ readonly relating: string;
26
+ readonly related: string;
27
+ }
28
+ export interface Outline2 {
29
+ readonly outer: readonly Base.Point2[];
30
+ readonly holes: readonly (readonly Base.Point2[])[];
31
+ }
32
+ export type MeasuredUnit = "LENGTHUNIT" | "AREAUNIT" | "VOLUMEUNIT" | "PLANEANGLEUNIT";
33
+ export interface NewProject {
34
+ readonly name: string;
35
+ readonly siteName: string;
36
+ readonly buildingName: string;
37
+ readonly lengthUnit: Inputs.IFC.lengthUnitEnum;
38
+ readonly seed: string | undefined;
39
+ readonly header: IfcFileHeader;
40
+ }
41
+ export interface LayerSpec {
42
+ readonly material: string | undefined;
43
+ readonly thickness: number;
44
+ readonly name: string | undefined;
45
+ }
46
+ export interface SurfaceColour {
47
+ readonly red: number;
48
+ readonly green: number;
49
+ readonly blue: number;
50
+ readonly transparency: number;
51
+ }
52
+ export interface PropertySpec {
53
+ readonly name: string;
54
+ readonly value: string | number | boolean;
55
+ readonly type: string | undefined;
56
+ }
57
+ export interface WallSpec {
58
+ readonly storey: number;
59
+ readonly id: string | undefined;
60
+ readonly name: string | undefined;
61
+ readonly start: Base.Point2;
62
+ readonly end: Base.Point2;
63
+ readonly height: number;
64
+ readonly baseOffset: number;
65
+ readonly layerSet: number;
66
+ readonly alignment: Inputs.IFC.wallAlignmentEnum;
67
+ readonly wallType: number | undefined;
68
+ readonly predefinedType: string | undefined;
69
+ }
70
+ export type WallEnd = "ATSTART" | "ATEND" | "ATPATH";
71
+ export interface WallGeometry {
72
+ readonly wall: number;
73
+ readonly frame: Frame3;
74
+ readonly start: Base.Point2;
75
+ readonly end: Base.Point2;
76
+ readonly direction: Base.Vector2;
77
+ readonly length: number;
78
+ readonly low: number;
79
+ readonly high: number;
80
+ readonly height: number;
81
+ readonly base: number;
82
+ readonly body: number | undefined;
83
+ readonly usage: number;
84
+ }
85
+ export interface WallCuts {
86
+ readonly start: Line2 | undefined;
87
+ readonly end: Line2 | undefined;
88
+ }
89
+ export interface WallJoin {
90
+ readonly mine: WallEnd;
91
+ readonly other: number;
92
+ readonly theirs: WallEnd;
93
+ readonly relationship: number;
94
+ }
95
+ export interface Meeting {
96
+ readonly stemEnd: WallEnd;
97
+ readonly otherEnd: WallEnd;
98
+ readonly gap: number;
99
+ }
100
+ export interface WallChange {
101
+ readonly start: Base.Point2 | undefined;
102
+ readonly end: Base.Point2 | undefined;
103
+ readonly bottom: number | undefined;
104
+ readonly height: number | undefined;
105
+ readonly layerSet: number | undefined;
106
+ readonly alignment: Inputs.IFC.wallAlignmentEnum | undefined;
107
+ }
108
+ export interface WallBody {
109
+ readonly height: number;
110
+ readonly base: number;
111
+ readonly halfSpaces: readonly number[];
112
+ }
113
+ export interface OpeningChange {
114
+ readonly offset: number | undefined;
115
+ readonly sill: number | undefined;
116
+ readonly width: number | undefined;
117
+ readonly height: number | undefined;
118
+ }
119
+ export interface SlabOpeningSpec {
120
+ readonly slab: number;
121
+ readonly id: string | undefined;
122
+ readonly name: string | undefined;
123
+ readonly outline: readonly Base.Point2[];
124
+ }
125
+ export interface WallOpeningPlace {
126
+ readonly opening: number;
127
+ readonly placement: number;
128
+ readonly offset: number;
129
+ readonly sill: number;
130
+ readonly width: number;
131
+ readonly height: number;
132
+ }
133
+ export interface WallOpeningSpec {
134
+ readonly wall: number;
135
+ readonly id: string | undefined;
136
+ readonly name: string | undefined;
137
+ readonly offset: number;
138
+ readonly sill: number;
139
+ readonly width: number;
140
+ readonly height: number;
141
+ }
142
+ export interface WallOpening {
143
+ readonly opening: number;
144
+ readonly placement: number;
145
+ readonly wallFace: number;
146
+ readonly thickness: number;
147
+ }
148
+ export interface DoorTypeSpec {
149
+ readonly id: string | undefined;
150
+ readonly name: string;
151
+ readonly width: number;
152
+ readonly height: number;
153
+ readonly liningThickness: number;
154
+ readonly liningDepth: number;
155
+ readonly panelThickness: number;
156
+ readonly operation: Inputs.IFC.doorOperationEnum;
157
+ readonly liningMaterial: string | undefined;
158
+ readonly panelMaterial: string | undefined;
159
+ readonly handle: Inputs.IFC.doorHandleEnum;
160
+ readonly handleMaterial: string | undefined;
161
+ readonly hardware: HandleSizes;
162
+ }
163
+ export interface HandleSizes {
164
+ readonly inset: number;
165
+ readonly leverHeight: number;
166
+ readonly leverStandoff: number;
167
+ readonly leverSection: number;
168
+ readonly leverLength: number;
169
+ readonly pullBarLength: number;
170
+ readonly pullBarMiddle: number;
171
+ readonly pullBarStandoff: number;
172
+ readonly pullBarSection: number;
173
+ readonly pullBarPost: number;
174
+ readonly pullBarPostInset: number;
175
+ }
176
+ export interface WindowTypeSpec {
177
+ readonly id: string | undefined;
178
+ readonly name: string;
179
+ readonly width: number;
180
+ readonly height: number;
181
+ readonly frameThickness: number;
182
+ readonly frameDepth: number;
183
+ readonly glassThickness: number;
184
+ readonly frameMaterial: string | undefined;
185
+ readonly glassMaterial: string | undefined;
186
+ }
187
+ export interface TerrainSpec {
188
+ readonly id: string | undefined;
189
+ readonly name: string;
190
+ readonly outline: readonly Base.Point2[];
191
+ readonly holes: readonly (readonly Base.Point2[])[];
192
+ readonly depth: number;
193
+ readonly elevation: number;
194
+ readonly material: string | undefined;
195
+ }
196
+ export interface AssemblySpec {
197
+ readonly parts: readonly number[];
198
+ readonly id: string | undefined;
199
+ readonly name: string | undefined;
200
+ readonly predefinedType: string;
201
+ readonly objectType: string | undefined;
202
+ }
203
+ export interface TreeSpec {
204
+ readonly id: string | undefined;
205
+ readonly name: string;
206
+ readonly species: string;
207
+ readonly position: Base.Point2;
208
+ readonly elevation: number;
209
+ readonly height: number;
210
+ readonly crownRadius: number;
211
+ readonly trunkRadius: number;
212
+ readonly crownMaterial: string | undefined;
213
+ readonly trunkMaterial: string | undefined;
214
+ }
215
+ export interface CrownMesh {
216
+ readonly mesh: MeshArrays;
217
+ readonly centre: number;
218
+ }
219
+ export interface MaterialPart {
220
+ readonly name: string;
221
+ readonly items: readonly number[];
222
+ readonly material: string | undefined;
223
+ }
224
+ export interface FillingSpec {
225
+ readonly wall: number;
226
+ readonly type: number;
227
+ readonly id: string | undefined;
228
+ readonly name: string | undefined;
229
+ readonly offset: number;
230
+ readonly sill: number;
231
+ }
232
+ export interface TypeBounds {
233
+ readonly min: Base.Point3;
234
+ readonly max: Base.Point3;
235
+ }
236
+ export interface RectangleProfile {
237
+ readonly kind: Inputs.IFC.profileKindEnum.rectangle;
238
+ readonly width: number;
239
+ readonly depth: number;
240
+ }
241
+ export interface CircleProfile {
242
+ readonly kind: Inputs.IFC.profileKindEnum.circle;
243
+ readonly radius: number;
244
+ }
245
+ export interface IShapeProfile {
246
+ readonly kind: Inputs.IFC.profileKindEnum.iShape;
247
+ readonly width: number;
248
+ readonly depth: number;
249
+ readonly webThickness: number;
250
+ readonly flangeThickness: number;
251
+ }
252
+ export type ProfileSpec = RectangleProfile | CircleProfile | IShapeProfile;
253
+ export interface SpaceSpec {
254
+ readonly storey: number;
255
+ readonly id: string | undefined;
256
+ readonly name: string | undefined;
257
+ readonly longName: string | undefined;
258
+ readonly outline: readonly Base.Point2[];
259
+ readonly height: number;
260
+ readonly baseOffset: number;
261
+ readonly predefinedType: string;
262
+ }
263
+ export interface RoofSpec {
264
+ readonly storey: number;
265
+ readonly id: string | undefined;
266
+ readonly name: string | undefined;
267
+ readonly outline: readonly Base.Point2[];
268
+ readonly kind: Inputs.IFC.roofKindEnum;
269
+ readonly pitch: number;
270
+ readonly layerSet: number;
271
+ readonly overhang: number;
272
+ readonly baseOffset: number;
273
+ }
274
+ export interface RoofPlane {
275
+ readonly origin: Base.Point2;
276
+ readonly along: Base.Vector2;
277
+ readonly inward: Base.Vector2;
278
+ readonly outline: readonly Base.Point2[];
279
+ }
280
+ export interface Linear2 {
281
+ readonly a: number;
282
+ readonly b: number;
283
+ readonly c: number;
284
+ }
285
+ export interface Bounds {
286
+ readonly tops: readonly Linear2[];
287
+ readonly bottoms: readonly Linear2[];
288
+ readonly sides: readonly Linear2[];
289
+ }
290
+ export interface BoundPair {
291
+ readonly top: Linear2;
292
+ readonly bottom: Linear2;
293
+ readonly keeps: readonly Linear2[];
294
+ }
295
+ export interface ProfileShape {
296
+ readonly area: number;
297
+ readonly perimeter: number;
298
+ readonly outline: readonly Base.Point2[] | undefined;
299
+ }
300
+ export interface Plane3 {
301
+ readonly origin: Base.Point3;
302
+ readonly normal: Base.Vector3;
303
+ }
304
+ export type QuantityKind = "length" | "area" | "volume";
305
+ export interface MeasuredQuantity {
306
+ readonly name: string;
307
+ readonly kind: QuantityKind;
308
+ readonly value: number;
309
+ }
310
+ export interface MeasuredSet {
311
+ readonly name: string;
312
+ readonly quantities: readonly MeasuredQuantity[];
313
+ }
314
+ export interface ExtrudedBody {
315
+ readonly solid: number;
316
+ readonly frame: Frame3;
317
+ readonly depth: number;
318
+ readonly shape: ProfileShape;
319
+ }
320
+ export interface SlabSpec {
321
+ readonly storey: number;
322
+ readonly id: string | undefined;
323
+ readonly name: string | undefined;
324
+ readonly outline: readonly Base.Point2[];
325
+ readonly holes: readonly (readonly Base.Point2[])[];
326
+ readonly layerSet: number;
327
+ readonly topOffset: number;
328
+ readonly predefinedType: string;
329
+ }
330
+ export interface MemberSpec {
331
+ readonly storey: number;
332
+ readonly id: string | undefined;
333
+ readonly name: string | undefined;
334
+ readonly start: Base.Point3;
335
+ readonly end: Base.Point3;
336
+ readonly profile: ProfileSpec;
337
+ readonly rotation: number;
338
+ readonly material: number | undefined;
339
+ readonly predefinedType: string;
340
+ }
341
+ export interface ContextKey {
342
+ readonly contextType: string;
343
+ readonly identifier: string;
344
+ readonly view: string;
345
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { EntityReader } from "./build-types";
2
+ export declare function requirePoint(point: unknown, size: number, what: string): void;
3
+ export declare function requireOutline(points: unknown, what: string): void;
4
+ export declare function requirePositive(value: number, what: string): void;
5
+ export declare function requireFinite(value: number, what: string): void;
6
+ export declare function requiredReference(reader: EntityReader, id: number, attribute: string): number;
@@ -0,0 +1,32 @@
1
+ import { isReference } from "../step/values";
2
+ import { MIN_OUTLINE_POINTS, POINT2_SIZE } from "./constants";
3
+ const COUNT_WORDS = ["no", "one", "two", "three"];
4
+ export function requirePoint(point, size, what) {
5
+ var _a;
6
+ if (!Array.isArray(point) || point.length !== size || !point.every(Number.isFinite)) {
7
+ throw new TypeError(`The ${what} must be ${(_a = COUNT_WORDS[size]) !== null && _a !== void 0 ? _a : size} finite numbers`);
8
+ }
9
+ }
10
+ export function requireOutline(points, what) {
11
+ if (!Array.isArray(points) || points.length < MIN_OUTLINE_POINTS) {
12
+ throw new TypeError(`The ${what} must be a list of at least ${MIN_OUTLINE_POINTS} [x, y] points`);
13
+ }
14
+ points.forEach((point, index) => requirePoint(point, POINT2_SIZE, `${what}'s point ${index}`));
15
+ }
16
+ export function requirePositive(value, what) {
17
+ if (!(value > 0) || !Number.isFinite(value)) {
18
+ throw new RangeError(`The ${what} must be more than zero, got ${value}`);
19
+ }
20
+ }
21
+ export function requireFinite(value, what) {
22
+ if (!Number.isFinite(value)) {
23
+ throw new RangeError(`The ${what} must be a finite number, got ${value}`);
24
+ }
25
+ }
26
+ export function requiredReference(reader, id, attribute) {
27
+ const value = reader.attribute(id, attribute);
28
+ if (!isReference(value)) {
29
+ throw new Error(`#${id} has no ${attribute}`);
30
+ }
31
+ return value.ref;
32
+ }
@@ -0,0 +1,27 @@
1
+ import type { RelationshipRoles } from "./build-types";
2
+ export declare const DEFAULT_PRECISION_METRES = 0.00001;
3
+ export declare const METRES_TO_MILLIMETRES = 1000;
4
+ export declare const LENGTH_PREFIXES: Readonly<Record<string, number>>;
5
+ export declare const GEOMETRY_TOLERANCE_METRES = 0.000001;
6
+ export declare const PARALLEL_TOLERANCE = 1e-9;
7
+ export declare const OPENING_MARGIN_RATIO = 0.25;
8
+ export declare const DEGREES_TO_RADIANS: number;
9
+ export declare const VERTICAL_COSINE: number;
10
+ export declare const POINT2_SIZE = 2;
11
+ export declare const POINT3_SIZE = 3;
12
+ export declare const TRIANGLE_CORNERS = 3;
13
+ export declare const MIN_OUTLINE_POINTS = 3;
14
+ export declare const CONTAINMENT: RelationshipRoles;
15
+ export declare const MATERIAL_ASSOCIATION: RelationshipRoles;
16
+ export declare const TYPE_DEFINITION: RelationshipRoles;
17
+ export declare const AGGREGATION: RelationshipRoles;
18
+ export declare const DECLARATION: RelationshipRoles;
19
+ export declare const PROPERTY_DEFINITION: RelationshipRoles;
20
+ export declare const VOIDING: RelationshipRoles;
21
+ export declare const FILLING: RelationshipRoles;
22
+ export declare const WALL_CONNECTION = "IfcRelConnectsPathElements";
23
+ export declare const WALL_ENDS: readonly ["ATSTART", "ATEND", "ATPATH"];
24
+ export declare const MINUTES_PER_DEGREE = 60;
25
+ export declare const SECONDS_PER_DEGREE = 3600;
26
+ export declare const MILLIONTHS_PER_SECOND = 1000000;
27
+ export declare const COMPOUND_ANGLE_PARTS = 3;
@@ -0,0 +1,43 @@
1
+ export const DEFAULT_PRECISION_METRES = 1e-5;
2
+ export const METRES_TO_MILLIMETRES = 1000;
3
+ export const LENGTH_PREFIXES = {
4
+ EXA: 1e18,
5
+ PETA: 1e15,
6
+ TERA: 1e12,
7
+ GIGA: 1e9,
8
+ MEGA: 1e6,
9
+ KILO: 1e3,
10
+ HECTO: 1e2,
11
+ DECA: 1e1,
12
+ DECI: 1e-1,
13
+ CENTI: 1e-2,
14
+ MILLI: 1e-3,
15
+ MICRO: 1e-6,
16
+ NANO: 1e-9,
17
+ PICO: 1e-12,
18
+ FEMTO: 1e-15,
19
+ ATTO: 1e-18,
20
+ };
21
+ export const GEOMETRY_TOLERANCE_METRES = 1e-6;
22
+ export const PARALLEL_TOLERANCE = 1e-9;
23
+ export const OPENING_MARGIN_RATIO = 0.25;
24
+ export const DEGREES_TO_RADIANS = Math.PI / 180;
25
+ export const VERTICAL_COSINE = 1 - 1e-9;
26
+ export const POINT2_SIZE = 2;
27
+ export const POINT3_SIZE = 3;
28
+ export const TRIANGLE_CORNERS = 3;
29
+ export const MIN_OUTLINE_POINTS = 3;
30
+ export const CONTAINMENT = { relationship: "IfcRelContainedInSpatialStructure", relating: "RelatingStructure", related: "RelatedElements" };
31
+ export const MATERIAL_ASSOCIATION = { relationship: "IfcRelAssociatesMaterial", relating: "RelatingMaterial", related: "RelatedObjects" };
32
+ export const TYPE_DEFINITION = { relationship: "IfcRelDefinesByType", relating: "RelatingType", related: "RelatedObjects" };
33
+ export const AGGREGATION = { relationship: "IfcRelAggregates", relating: "RelatingObject", related: "RelatedObjects" };
34
+ export const DECLARATION = { relationship: "IfcRelDeclares", relating: "RelatingContext", related: "RelatedDefinitions" };
35
+ export const PROPERTY_DEFINITION = { relationship: "IfcRelDefinesByProperties", relating: "RelatingPropertyDefinition", related: "RelatedObjects" };
36
+ export const VOIDING = { relationship: "IfcRelVoidsElement", relating: "RelatingBuildingElement", related: "RelatedOpeningElement" };
37
+ export const FILLING = { relationship: "IfcRelFillsElement", relating: "RelatingOpeningElement", related: "RelatedBuildingElement" };
38
+ export const WALL_CONNECTION = "IfcRelConnectsPathElements";
39
+ export const WALL_ENDS = ["ATSTART", "ATEND", "ATPATH"];
40
+ export const MINUTES_PER_DEGREE = 60;
41
+ export const SECONDS_PER_DEGREE = 3600;
42
+ export const MILLIONTHS_PER_SECOND = 1e6;
43
+ export const COMPOUND_ANGLE_PARTS = 3;
@@ -0,0 +1,9 @@
1
+ import type { IfcTransaction } from "../model/transaction";
2
+ import type { ContextKey, ModelReader } from "./build-types";
3
+ import type { EntityWriter } from "./entity-writer";
4
+ export declare const BODY_CONTEXT: ContextKey;
5
+ export declare const AXIS_CONTEXT: ContextKey;
6
+ export declare function findContext(reader: ModelReader, key: ContextKey): number | undefined;
7
+ export declare function contextFor(tx: IfcTransaction, writer: EntityWriter, key: ContextKey): number;
8
+ export declare function bodyContext(tx: IfcTransaction, writer: EntityWriter): number;
9
+ export declare function axisContext(tx: IfcTransaction, writer: EntityWriter): number;
@@ -0,0 +1,52 @@
1
+ import { enumValue, isEnumeration, isReference, ref } from "../step/values";
2
+ export const BODY_CONTEXT = { contextType: "Model", identifier: "Body", view: "MODEL_VIEW" };
3
+ export const AXIS_CONTEXT = { contextType: "Plan", identifier: "Axis", view: "GRAPH_VIEW" };
4
+ const SUB_CONTEXT = "IfcGeometricRepresentationSubContext";
5
+ const known = new WeakMap();
6
+ function parentType(reader, context) {
7
+ const parent = reader.attribute(context, "ParentContext");
8
+ return isReference(parent) ? reader.attribute(parent.ref, "ContextType") : undefined;
9
+ }
10
+ export function findContext(reader, key) {
11
+ var _a;
12
+ const candidates = reader.byType(SUB_CONTEXT).filter((context) => reader.attribute(context.id, "ContextIdentifier") === key.identifier);
13
+ const exact = candidates.find((context) => {
14
+ const view = reader.attribute(context.id, "TargetView");
15
+ return isEnumeration(view) && view.enum === key.view && parentType(reader, context.id) === key.contextType;
16
+ });
17
+ return (_a = (exact !== null && exact !== void 0 ? exact : candidates[0])) === null || _a === void 0 ? void 0 : _a.id;
18
+ }
19
+ function createContext(tx, writer, key) {
20
+ var _a;
21
+ const parents = tx.byType("IfcGeometricRepresentationContext").filter((context) => context.type === "IfcGeometricRepresentationContext");
22
+ const parent = (_a = parents.find((context) => tx.attribute(context.id, "ContextType") === key.contextType)) !== null && _a !== void 0 ? _a : parents.find((context) => tx.attribute(context.id, "ContextType") === BODY_CONTEXT.contextType);
23
+ if (!parent) {
24
+ throw new Error(`The model has no geometric representation context to hold its ${key.identifier} representations`);
25
+ }
26
+ return writer.create(SUB_CONTEXT, {
27
+ ContextIdentifier: key.identifier,
28
+ ContextType: tx.attribute(parent.id, "ContextType"),
29
+ ParentContext: ref(parent.id),
30
+ TargetView: enumValue(key.view),
31
+ });
32
+ }
33
+ export function contextFor(tx, writer, key) {
34
+ var _a;
35
+ let contexts = known.get(tx);
36
+ if (!contexts) {
37
+ contexts = new Map();
38
+ known.set(tx, contexts);
39
+ }
40
+ let context = contexts.get(key);
41
+ if (context === undefined) {
42
+ context = (_a = findContext(tx, key)) !== null && _a !== void 0 ? _a : createContext(tx, writer, key);
43
+ contexts.set(key, context);
44
+ }
45
+ return context;
46
+ }
47
+ export function bodyContext(tx, writer) {
48
+ return contextFor(tx, writer, BODY_CONTEXT);
49
+ }
50
+ export function axisContext(tx, writer) {
51
+ return contextFor(tx, writer, AXIS_CONTEXT);
52
+ }
@@ -0,0 +1,3 @@
1
+ import type { Base } from "@bitbybit-dev/base";
2
+ import type { ModelReader } from "./build-types";
3
+ export declare function polylinePoints(reader: ModelReader, curve: number): Base.Point2[] | undefined;
@@ -0,0 +1,23 @@
1
+ import { isList } from "../step/values";
2
+ import { requiredReference } from "./checks";
3
+ import { numbersOf, pointOf } from "./placement";
4
+ export function polylinePoints(reader, curve) {
5
+ const type = reader.entity(curve).type;
6
+ if (type === "IfcIndexedPolyCurve") {
7
+ const list = requiredReference(reader, curve, "Points");
8
+ const coordinates = reader.attribute(list, "CoordList");
9
+ return (isList(coordinates) ? coordinates : []).map((item, index) => {
10
+ var _a, _b;
11
+ const numbers = numbersOf(item, `#${list} point ${index}`);
12
+ return [(_a = numbers[0]) !== null && _a !== void 0 ? _a : 0, (_b = numbers[1]) !== null && _b !== void 0 ? _b : 0];
13
+ });
14
+ }
15
+ if (type === "IfcPolyline") {
16
+ const list = reader.attribute(curve, "Points");
17
+ return (isList(list) ? list : []).map((item) => {
18
+ const point = pointOf(reader, item);
19
+ return [point[0], point[1]];
20
+ });
21
+ }
22
+ return undefined;
23
+ }