@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,87 @@
1
+ import { textValue } from "../../step/values";
2
+ import { resolveDto } from "@bitbybit-dev/base";
3
+ import { millimetresPerUnit } from "../../build/project";
4
+ import { modelRecipe } from "../../geometry/elements";
5
+ import * as Inputs from "../inputs";
6
+ import { lengthTolerance, modelOf, resolveId } from "./service-support";
7
+ function described(memo, inputs) {
8
+ var _a;
9
+ const model = modelOf(inputs.model);
10
+ const elements = inputs.elements;
11
+ if (elements !== undefined && !Array.isArray(elements)) {
12
+ throw new TypeError("Expected the elements as a list of GlobalIds or ids");
13
+ }
14
+ const key = JSON.stringify([elements !== null && elements !== void 0 ? elements : null, inputs.groupByClass]);
15
+ const last = memo.get(model);
16
+ if ((last === null || last === void 0 ? void 0 : last.key) === key) {
17
+ return last.described;
18
+ }
19
+ const globalIds = (_a = inputs.elements) === null || _a === void 0 ? void 0 : _a.map((element) => selectedGlobalId(model, element));
20
+ const result = modelRecipe(model, globalIds, millimetresPerUnit(model), lengthTolerance(model), inputs.groupByClass);
21
+ memo.set(model, { key, described: result });
22
+ return result;
23
+ }
24
+ const PRODUCT = "IfcProduct";
25
+ function selectedGlobalId(model, element) {
26
+ var _a;
27
+ const owners = model.globalIdOwners(element);
28
+ if (owners.length > 1 && owners.every((owner) => { var _a; return model.schema.isSubtypeOf((_a = model.typeOf(owner)) !== null && _a !== void 0 ? _a : "", PRODUCT); })) {
29
+ return element;
30
+ }
31
+ return (_a = textValue(model.attribute(resolveId(model, element, PRODUCT, "element"), "GlobalId"))) !== null && _a !== void 0 ? _a : "";
32
+ }
33
+ /**
34
+ * Describes a model's geometry as a recipe: data that a geometry kernel builds into solids or
35
+ * meshes, one result per element, with the openings of walls and slabs cut through them and each
36
+ * door or window type described once however many times it is placed.
37
+ *
38
+ * The recipe stays in the model's units and its Z up; each result is tagged with its element's
39
+ * `globalId`, `type`, `name` and, when its material has a colour, `rgba`.
40
+ * @beta
41
+ */
42
+ export class IFCGeometry {
43
+ constructor() {
44
+ this.lastDescribed = new WeakMap();
45
+ }
46
+ /**
47
+ * Describes the geometry of a model's elements as a recipe, ready for a kernel to build.
48
+ *
49
+ * Each element with a body becomes one root, placed by its matrix and tagged with its GlobalId;
50
+ * openings are cut from their hosts rather than becoming roots. An element that cannot be
51
+ * described is left out, and `geometry.unsupported` lists it with the reason.
52
+ * @param inputs - The model and, optionally, the elements to describe
53
+ * @returns A recipe with one root per element
54
+ * @group recipes
55
+ * @shortname geometry recipe
56
+ * @drawable false
57
+ * @example
58
+ * ```typescript
59
+ * const recipe = await bitbybit.ifc.geometry.recipe({ model });
60
+ * console.log(recipe.roots.length, recipe.millimetresPerUnit);
61
+ * ```
62
+ */
63
+ recipe(inputs) {
64
+ const resolved = resolveDto(Inputs.IFC.GeometryDto, inputs);
65
+ return described(this.lastDescribed, resolved).recipe;
66
+ }
67
+ /**
68
+ * Lists the elements whose geometry `geometry.recipe` leaves out, each with what it could not
69
+ * describe, such as a profile type that is not supported yet.
70
+ *
71
+ * An element asked for in `elements` is listed too when it has no body to describe, such as an
72
+ * opening, a storey or an element without a 'Body' representation.
73
+ * @param inputs - The model and, optionally, the elements to check
74
+ * @returns The elements left out, empty when every one is described
75
+ * @group recipes
76
+ * @shortname unsupported geometry
77
+ * @drawable false
78
+ * @example
79
+ * ```typescript
80
+ * const problems = await bitbybit.ifc.geometry.unsupported({ model });
81
+ * problems.forEach((problem) => console.log(problem.type, problem.message));
82
+ * ```
83
+ */
84
+ unsupported(inputs) {
85
+ return described(this.lastDescribed, Object.assign(Object.assign({}, inputs), { groupByClass: true })).problems;
86
+ }
87
+ }
@@ -0,0 +1,17 @@
1
+ export * from "./model";
2
+ export * from "./spatial";
3
+ export * from "./spaces";
4
+ export * from "./materials";
5
+ export * from "./walls";
6
+ export * from "./openings";
7
+ export * from "./doors";
8
+ export * from "./windows";
9
+ export * from "./slabs";
10
+ export * from "./roofs";
11
+ export * from "./site";
12
+ export * from "./columns";
13
+ export * from "./beams";
14
+ export * from "./members";
15
+ export * from "./properties";
16
+ export * from "./quantities";
17
+ export * from "./geometry";
@@ -0,0 +1,17 @@
1
+ export * from "./model";
2
+ export * from "./spatial";
3
+ export * from "./spaces";
4
+ export * from "./materials";
5
+ export * from "./walls";
6
+ export * from "./openings";
7
+ export * from "./doors";
8
+ export * from "./windows";
9
+ export * from "./slabs";
10
+ export * from "./roofs";
11
+ export * from "./site";
12
+ export * from "./columns";
13
+ export * from "./beams";
14
+ export * from "./members";
15
+ export * from "./properties";
16
+ export * from "./quantities";
17
+ export * from "./geometry";
@@ -0,0 +1,46 @@
1
+ import type { IfcModel } from "../../model/model-types";
2
+ import * as Inputs from "../inputs";
3
+ /**
4
+ * The materials elements are made of: plain materials with an optional colour, and layer sets that
5
+ * stack materials into the thickness of a wall or slab. Materials and layer sets are referred to by
6
+ * their names, which are unique in a model.
7
+ * @beta
8
+ */
9
+ export declare class IFCMaterials {
10
+ /**
11
+ * Adds a material, which layer sets, columns and beams then refer to by its name.
12
+ *
13
+ * With a `color`, the material carries a surface style that viewers show it in.
14
+ * @param inputs - The model, the material's name, category, colour and transparency
15
+ * @returns A new model with the material
16
+ * @group materials
17
+ * @shortname add material
18
+ * @drawable false
19
+ * @example
20
+ * ```typescript
21
+ * model = await bitbybit.ifc.materials.add({ model, name: "Brick", category: "brick", color: "#b5651d" });
22
+ * ```
23
+ */
24
+ add(inputs: Inputs.IFC.AddMaterialDto<IfcModel>): IfcModel;
25
+ /**
26
+ * Adds a layer set: materials stacked in order, each with its thickness, which walls, wall types,
27
+ * slabs and roofs are then made of.
28
+ *
29
+ * A wall's first layer is on its right face, looking from its start to its end; a slab's or a
30
+ * roof's first layer is at its top. A layer's material must have been added before, by name.
31
+ * @param inputs - The model, the layer set's name and its layers
32
+ * @returns A new model with the layer set
33
+ * @group materials
34
+ * @shortname add layer set
35
+ * @drawable false
36
+ * @example
37
+ * ```typescript
38
+ * model = await bitbybit.ifc.materials.addLayerSet({
39
+ * model,
40
+ * name: "Exterior wall",
41
+ * layers: [{ material: "Brick", thickness: 115 }, { material: "Insulation", thickness: 100 }],
42
+ * });
43
+ * ```
44
+ */
45
+ addLayerSet(inputs: Inputs.IFC.AddLayerSetDto<IfcModel>): IfcModel;
46
+ }
@@ -0,0 +1,86 @@
1
+ import { resolveDto } from "@bitbybit-dev/base";
2
+ import { createLayerSet, createMaterial } from "../../build/materials";
3
+ import * as Inputs from "../inputs";
4
+ import { DEFAULT_MILLIMETRES } from "./defaults.constants";
5
+ import { editModel, lengthIn, modelOf } from "./service-support";
6
+ const HEX_COLOUR = /^#?([0-9a-fA-F]{6})$/;
7
+ const HEX_RADIX = 16;
8
+ const CHANNEL_MAX = 255;
9
+ const GREEN_AT = 2;
10
+ const BLUE_AT = 4;
11
+ function parseHexColour(color, transparency) {
12
+ const match = HEX_COLOUR.exec(color);
13
+ if (!match) {
14
+ throw new Error(`A colour is written as hex such as #b5651d, got '${color}'`);
15
+ }
16
+ const hex = match[1];
17
+ const channel = (at) => Number.parseInt(hex.slice(at, at + 2), HEX_RADIX) / CHANNEL_MAX;
18
+ return { red: channel(0), green: channel(GREEN_AT), blue: channel(BLUE_AT), transparency };
19
+ }
20
+ /**
21
+ * The materials elements are made of: plain materials with an optional colour, and layer sets that
22
+ * stack materials into the thickness of a wall or slab. Materials and layer sets are referred to by
23
+ * their names, which are unique in a model.
24
+ * @beta
25
+ */
26
+ export class IFCMaterials {
27
+ /**
28
+ * Adds a material, which layer sets, columns and beams then refer to by its name.
29
+ *
30
+ * With a `color`, the material carries a surface style that viewers show it in.
31
+ * @param inputs - The model, the material's name, category, colour and transparency
32
+ * @returns A new model with the material
33
+ * @group materials
34
+ * @shortname add material
35
+ * @drawable false
36
+ * @example
37
+ * ```typescript
38
+ * model = await bitbybit.ifc.materials.add({ model, name: "Brick", category: "brick", color: "#b5651d" });
39
+ * ```
40
+ */
41
+ add(inputs) {
42
+ const resolved = resolveDto(Inputs.IFC.AddMaterialDto, inputs);
43
+ const model = modelOf(resolved.model);
44
+ if (!(resolved.transparency >= 0 && resolved.transparency <= 1)) {
45
+ throw new RangeError(`Transparency goes from 0 to 1, got ${resolved.transparency}`);
46
+ }
47
+ const colour = resolved.color === undefined ? undefined : parseHexColour(resolved.color, resolved.transparency);
48
+ return editModel(model, (tx, writer) => {
49
+ createMaterial(tx, writer, resolved.name, resolved.category, colour);
50
+ });
51
+ }
52
+ /**
53
+ * Adds a layer set: materials stacked in order, each with its thickness, which walls, wall types,
54
+ * slabs and roofs are then made of.
55
+ *
56
+ * A wall's first layer is on its right face, looking from its start to its end; a slab's or a
57
+ * roof's first layer is at its top. A layer's material must have been added before, by name.
58
+ * @param inputs - The model, the layer set's name and its layers
59
+ * @returns A new model with the layer set
60
+ * @group materials
61
+ * @shortname add layer set
62
+ * @drawable false
63
+ * @example
64
+ * ```typescript
65
+ * model = await bitbybit.ifc.materials.addLayerSet({
66
+ * model,
67
+ * name: "Exterior wall",
68
+ * layers: [{ material: "Brick", thickness: 115 }, { material: "Insulation", thickness: 100 }],
69
+ * });
70
+ * ```
71
+ */
72
+ addLayerSet(inputs) {
73
+ const resolved = resolveDto(Inputs.IFC.AddLayerSetDto, inputs);
74
+ const model = modelOf(resolved.model);
75
+ if (!Array.isArray(resolved.layers)) {
76
+ throw new TypeError("Expected the layers as a list");
77
+ }
78
+ const layers = resolved.layers.map((layer) => {
79
+ const full = resolveDto(Inputs.IFC.MaterialLayerDto, layer);
80
+ return { material: full.material, thickness: lengthIn(model, full.thickness, DEFAULT_MILLIMETRES.layerThickness), name: full.name };
81
+ });
82
+ return editModel(model, (tx, writer) => {
83
+ createLayerSet(tx, writer, resolved.name, layers);
84
+ });
85
+ }
86
+ }
@@ -0,0 +1,7 @@
1
+ import type { ProfileSpec } from "../../build/build-types";
2
+ import type { ModelSnapshot } from "../../model/snapshot";
3
+ import type { IfcTransaction } from "../../model/transaction";
4
+ import type * as Resolved from "../resolved-inputs";
5
+ export declare function profileOf(model: ModelSnapshot, resolved: Resolved.IFC.AddColumnDto<unknown> | Resolved.IFC.AddBeamDto<unknown> | Resolved.IFC.AddMemberDto<unknown>): ProfileSpec;
6
+ export declare function memberMaterial(tx: IfcTransaction, name: string | undefined): number | undefined;
7
+ export declare function finiteRotation(rotation: number): void;
@@ -0,0 +1,29 @@
1
+ import { requireFinite } from "../../build/checks";
2
+ import { requireMaterial } from "../../build/materials";
3
+ import * as Inputs from "../inputs";
4
+ import { DEFAULT_MILLIMETRES } from "./defaults.constants";
5
+ import { lengthIn, oneOf } from "./service-support";
6
+ export function profileOf(model, resolved) {
7
+ const width = lengthIn(model, resolved.width, DEFAULT_MILLIMETRES.sectionWidth);
8
+ const depth = lengthIn(model, resolved.depth, DEFAULT_MILLIMETRES.sectionDepth);
9
+ switch (oneOf(resolved.profile, Inputs.IFC.profileKindEnum, "profile")) {
10
+ case Inputs.IFC.profileKindEnum.circle:
11
+ return { kind: Inputs.IFC.profileKindEnum.circle, radius: lengthIn(model, resolved.radius, DEFAULT_MILLIMETRES.sectionRadius) };
12
+ case Inputs.IFC.profileKindEnum.iShape:
13
+ return {
14
+ kind: Inputs.IFC.profileKindEnum.iShape,
15
+ width,
16
+ depth,
17
+ webThickness: lengthIn(model, resolved.webThickness, DEFAULT_MILLIMETRES.webThickness),
18
+ flangeThickness: lengthIn(model, resolved.flangeThickness, DEFAULT_MILLIMETRES.flangeThickness),
19
+ };
20
+ default:
21
+ return { kind: Inputs.IFC.profileKindEnum.rectangle, width, depth };
22
+ }
23
+ }
24
+ export function memberMaterial(tx, name) {
25
+ return name === undefined ? undefined : requireMaterial(tx, name);
26
+ }
27
+ export function finiteRotation(rotation) {
28
+ requireFinite(rotation, "rotation in degrees");
29
+ }
@@ -0,0 +1,24 @@
1
+ import type { IfcModel } from "../../model/model-types";
2
+ import * as Inputs from "../inputs";
3
+ /**
4
+ * Members: the linear parts of frames, roofs and facades that are neither columns nor beams, such as
5
+ * braces, rafters, studs and mullions, each a section swept straight between two points.
6
+ * @beta
7
+ */
8
+ export declare class IFCMembers {
9
+ /**
10
+ * Adds a member from `start` to `end` in a storey, its section centred on the line between them,
11
+ * as a brace, a rafter, a stud, a mullion or another kind. The section is chosen by `profile` and
12
+ * turned by `rotation` as for beams.
13
+ * @param inputs - The model, the storey, the two ends, the section and the kind of member
14
+ * @returns A new model with the member
15
+ * @group create
16
+ * @shortname add member
17
+ * @drawable false
18
+ * @example
19
+ * ```typescript
20
+ * model = await bitbybit.ifc.members.add({ model, storey: "ground", start: [0, 0, 0], end: [4000, 0, 3000], predefinedType: Bit.Inputs.IFC.memberPredefinedTypeEnum.brace, width: 100, depth: 100 });
21
+ * ```
22
+ */
23
+ add(inputs: Inputs.IFC.AddMemberDto<IfcModel>): IfcModel;
24
+ }
@@ -0,0 +1,51 @@
1
+ import { resolveDto } from "@bitbybit-dev/base";
2
+ import { requirePoint } from "../../build/checks";
3
+ import { POINT3_SIZE } from "../../build/constants";
4
+ import { createMember } from "../../build/slabs-columns-beams";
5
+ import * as Inputs from "../inputs";
6
+ import { finiteRotation, memberMaterial, profileOf } from "./member-support";
7
+ import { editModel, modelOf, oneOf, resolveId } from "./service-support";
8
+ /**
9
+ * Members: the linear parts of frames, roofs and facades that are neither columns nor beams, such as
10
+ * braces, rafters, studs and mullions, each a section swept straight between two points.
11
+ * @beta
12
+ */
13
+ export class IFCMembers {
14
+ /**
15
+ * Adds a member from `start` to `end` in a storey, its section centred on the line between them,
16
+ * as a brace, a rafter, a stud, a mullion or another kind. The section is chosen by `profile` and
17
+ * turned by `rotation` as for beams.
18
+ * @param inputs - The model, the storey, the two ends, the section and the kind of member
19
+ * @returns A new model with the member
20
+ * @group create
21
+ * @shortname add member
22
+ * @drawable false
23
+ * @example
24
+ * ```typescript
25
+ * model = await bitbybit.ifc.members.add({ model, storey: "ground", start: [0, 0, 0], end: [4000, 0, 3000], predefinedType: Bit.Inputs.IFC.memberPredefinedTypeEnum.brace, width: 100, depth: 100 });
26
+ * ```
27
+ */
28
+ add(inputs) {
29
+ const resolved = resolveDto(Inputs.IFC.AddMemberDto, inputs);
30
+ const model = modelOf(resolved.model);
31
+ requirePoint(resolved.start, POINT3_SIZE, "start");
32
+ requirePoint(resolved.end, POINT3_SIZE, "end");
33
+ finiteRotation(resolved.rotation);
34
+ const profile = profileOf(model, resolved);
35
+ const storey = resolveId(model, resolved.storey, "IfcBuildingStorey", "storey");
36
+ const predefinedType = oneOf(resolved.predefinedType, Inputs.IFC.memberPredefinedTypeEnum, "predefined type");
37
+ return editModel(model, (tx, writer) => {
38
+ createMember(tx, writer, "IfcMember", {
39
+ storey,
40
+ id: resolved.id,
41
+ name: resolved.name,
42
+ start: resolved.start,
43
+ end: resolved.end,
44
+ profile,
45
+ rotation: resolved.rotation,
46
+ material: memberMaterial(tx, resolved.material),
47
+ predefinedType,
48
+ });
49
+ });
50
+ }
51
+ }
@@ -0,0 +1,244 @@
1
+ import type { IfcModel } from "../../model/model-types";
2
+ import * as Inputs from "../inputs";
3
+ /**
4
+ * Creates, reads, writes and inspects whole IFC models. A model is a value: every method that
5
+ * changes one returns a new model and leaves the one it was given as it was, so a change can be
6
+ * undone by keeping the earlier model.
7
+ *
8
+ * Objects are found by their GlobalId or by the id given when they were added, such as `north-wall`,
9
+ * which the model turns into a GlobalId of its own. Storeys are in `spatial`, building elements in
10
+ * `walls`, `slabs`, `doors` and the rest.
11
+ * @beta
12
+ */
13
+ export declare class IFCModels {
14
+ /**
15
+ * Starts a new IFC4 model with a project, its site and one building, ready for storeys.
16
+ *
17
+ * Every length later given to the model is in `lengthUnit`, millimetres by default. With a
18
+ * `seed`, the same calls always write the same file; without one, the GlobalIds are random.
19
+ * @param inputs - The project's name, the site and building names, the length unit and a seed
20
+ * @returns A new model
21
+ * @group create
22
+ * @shortname create model
23
+ * @drawable false
24
+ * @example
25
+ * ```typescript
26
+ * let model = await bitbybit.ifc.model.create({ name: "House", seed: "house-1" });
27
+ * model = await bitbybit.ifc.spatial.addStorey({ model, id: "ground", name: "Ground floor", elevation: 0 });
28
+ * ```
29
+ */
30
+ create(inputs: Inputs.IFC.CreateModelDto): IfcModel;
31
+ /**
32
+ * Reads an IFC file into a model to inspect, change and write back.
33
+ *
34
+ * Entities are decoded only when asked for, and unchanged ones are written back exactly as read.
35
+ * An IFC2X3 file is read through IFC4, to be shown and queried; `upgradeToIfc4` makes it
36
+ * editable. An `.ifczip` archive is read from the `.ifc` file it holds.
37
+ * @param inputs - The file's text or bytes
38
+ * @returns The model the file holds
39
+ * @group io
40
+ * @shortname read ifc
41
+ * @drawable false
42
+ * @example
43
+ * ```typescript
44
+ * const model = await bitbybit.ifc.model.read({ data: ifcText });
45
+ * const summary = await bitbybit.ifc.model.summary({ model });
46
+ * ```
47
+ */
48
+ read(inputs: Inputs.IFC.ReadModelDto): IfcModel;
49
+ /**
50
+ * Turns a model read from an IFC2X3 file into an IFC4 model, which can be changed and is
51
+ * written as IFC4.
52
+ *
53
+ * New attributes stay unset, a newly required enumeration takes `NOTDEFINED`, sets lose repeats
54
+ * and a merged entity becomes its parent; other rows are written as read. Anything else stops
55
+ * the upgrade, naming the entity.
56
+ * @param inputs - The model
57
+ * @returns The upgraded model
58
+ * @group io
59
+ * @shortname upgrade to ifc4
60
+ * @drawable false
61
+ * @example
62
+ * ```typescript
63
+ * const old = await bitbybit.ifc.model.read({ data: ifc2x3Bytes });
64
+ * const model = await bitbybit.ifc.model.upgradeToIfc4({ model: old });
65
+ * ```
66
+ */
67
+ upgradeToIfc4(inputs: Inputs.IFC.ModelDto<IfcModel>): IfcModel;
68
+ /**
69
+ * Writes a model as the text of an `.ifc` file.
70
+ *
71
+ * The header records `fileName` and `timeStamp`; give a fixed `timeStamp` to write the same text
72
+ * every time. Entities read from a file and left unchanged are written as they were read, character
73
+ * for character.
74
+ * @param inputs - The model, the file name and the time stamp
75
+ * @returns The text of the IFC file
76
+ * @group io
77
+ * @shortname write ifc
78
+ * @drawable false
79
+ * @example
80
+ * ```typescript
81
+ * const text = await bitbybit.ifc.model.write({ model, fileName: "house.ifc" });
82
+ * ```
83
+ */
84
+ write(inputs: Inputs.IFC.WriteModelDto<IfcModel>): string;
85
+ /**
86
+ * Writes a model as the bytes of an `.ifc` file, at any size.
87
+ *
88
+ * The header records `fileName` and `timeStamp`, as `model.write`'s does. Entities read from a file
89
+ * and left unchanged are copied byte for byte, so a file of hundreds of megabytes writes in a moment,
90
+ * where its text would not fit one JavaScript string.
91
+ * @param inputs - The model, the file name and the time stamp
92
+ * @returns The bytes of the IFC file
93
+ * @group io
94
+ * @shortname write ifc bytes
95
+ * @drawable false
96
+ * @example
97
+ * ```typescript
98
+ * const bytes = await bitbybit.ifc.model.writeBytes({ model, fileName: "house.ifc" });
99
+ * ```
100
+ */
101
+ writeBytes(inputs: Inputs.IFC.WriteModelDto<IfcModel>): Uint8Array;
102
+ /**
103
+ * Describes what a model holds: its schema, its project, its unit, its storeys and how many
104
+ * elements of each type.
105
+ * @param inputs - The model
106
+ * @returns The model's summary
107
+ * @group query
108
+ * @shortname summary
109
+ * @drawable false
110
+ * @example
111
+ * ```typescript
112
+ * const summary = await bitbybit.ifc.model.summary({ model });
113
+ * console.log(summary.elementCounts.IfcWall);
114
+ * ```
115
+ */
116
+ summary(inputs: Inputs.IFC.ModelDto<IfcModel>): Inputs.IFC.ModelSummaryDto;
117
+ /**
118
+ * Reads where a model sits on the Earth: the map conversion that places its coordinates in a
119
+ * projected coordinate reference system, and its site's reference latitude, longitude and
120
+ * elevation. A file without them gives the defaults, with `mapped` and `located` false.
121
+ * @param inputs - The model
122
+ * @returns The model's georeference
123
+ * @group query
124
+ * @shortname georeference
125
+ * @drawable false
126
+ * @example
127
+ * ```typescript
128
+ * const georeference = await bitbybit.ifc.model.georeference({ model });
129
+ * console.log(georeference.crs, georeference.eastings, georeference.northings);
130
+ * ```
131
+ */
132
+ georeference(inputs: Inputs.IFC.ModelDto<IfcModel>): Inputs.IFC.GeoreferenceDto;
133
+ /**
134
+ * Lists the objects of one IFC type, its subtypes included, optionally only those standing in
135
+ * one storey or other spatial element. An aggregate's part stands where its whole stands.
136
+ *
137
+ * `type` is any type with a GlobalId, such as `IfcWall`, `IfcDoor` or `IfcElement` for every
138
+ * building element. The list is in the order the model holds them.
139
+ * @param inputs - The model, the type and an optional storey
140
+ * @returns Each object's GlobalId, type, name and the spatial element it stands in
141
+ * @group query
142
+ * @shortname elements
143
+ * @drawable false
144
+ * @example
145
+ * ```typescript
146
+ * const walls = await bitbybit.ifc.model.elements({ model, type: "IfcWall", storey: "ground" });
147
+ * ```
148
+ */
149
+ elements(inputs: Inputs.IFC.ElementsDto<IfcModel>): Inputs.IFC.ElementInfoDto[];
150
+ /**
151
+ * Describes one object of a model: its GlobalId, its type, its name and the spatial element it
152
+ * stands in.
153
+ * @param inputs - The model and the object
154
+ * @returns The object's GlobalId, type, name and the spatial element it stands in
155
+ * @group query
156
+ * @shortname element
157
+ * @drawable false
158
+ * @example
159
+ * ```typescript
160
+ * const wall = await bitbybit.ifc.model.element({ model, element: "north-wall" });
161
+ * ```
162
+ */
163
+ element(inputs: Inputs.IFC.ElementDto<IfcModel>): Inputs.IFC.ElementInfoDto;
164
+ /**
165
+ * Removes an element, an empty storey or space, or a type nothing is of, with what only it uses.
166
+ * A wall takes its openings with their doors and windows, and the walls it was joined to are
167
+ * trimmed again; a door or window leaves its opening; an opening takes its doors and windows.
168
+ * @param inputs - The model and the object
169
+ * @returns A new model without the object
170
+ * @group edit
171
+ * @shortname remove
172
+ * @drawable false
173
+ * @example
174
+ * ```typescript
175
+ * model = await bitbybit.ifc.model.remove({ model, element: "partition" });
176
+ * ```
177
+ */
178
+ remove(inputs: Inputs.IFC.ElementDto<IfcModel>): IfcModel;
179
+ /**
180
+ * Moves an element or a space, and turns it about the vertical through its own origin; what is
181
+ * placed on it, such as a wall's openings, moves with it. A joined wall moves with `walls.edit`,
182
+ * and an opening, door or window with `openings.edit`.
183
+ * @param inputs - The model, the element, how far to move it and how far to turn it
184
+ * @returns A new model with the element moved
185
+ * @group edit
186
+ * @shortname move
187
+ * @drawable false
188
+ * @example
189
+ * ```typescript
190
+ * model = await bitbybit.ifc.model.move({ model, element: "column-1", translation: [500, 0, 0], rotation: 45 });
191
+ * ```
192
+ */
193
+ move(inputs: Inputs.IFC.MoveElementDto<IfcModel>): IfcModel;
194
+ /**
195
+ * Sets one attribute of an object to a text, a number, true or false, such as a wall's `Name`,
196
+ * `Description` or `Tag`.
197
+ *
198
+ * The value is checked against the IFC schema, and an attribute that holds a reference, a derived
199
+ * attribute or the `GlobalId` cannot be set this way.
200
+ * @param inputs - The model, the object, the attribute's name and the new value
201
+ * @returns A new model with the attribute set
202
+ * @group edit
203
+ * @shortname set attribute
204
+ * @drawable false
205
+ * @example
206
+ * ```typescript
207
+ * model = await bitbybit.ifc.model.setAttribute({ model, element: "north-wall", attribute: "Description", value: "Load bearing" });
208
+ * ```
209
+ */
210
+ setAttribute(inputs: Inputs.IFC.SetAttributeDto<IfcModel>): IfcModel;
211
+ /**
212
+ * Reads one attribute of an object, such as a wall's `Name`, `Description` or `Tag`.
213
+ *
214
+ * The value comes back as the model holds it: a text, a number, true or false, `null` when the
215
+ * attribute is unset, `{ enum }` for an enumeration value, `{ type, value }` for a typed value,
216
+ * `{ ref }` for a reference to another entity, or a list of these.
217
+ * @param inputs - The model, the object and the attribute's name
218
+ * @returns The attribute's value
219
+ * @group query
220
+ * @shortname get attribute
221
+ * @drawable false
222
+ * @example
223
+ * ```typescript
224
+ * const description = await bitbybit.ifc.model.getAttribute({ model, element: "north-wall", attribute: "Description" });
225
+ * ```
226
+ */
227
+ getAttribute(inputs: Inputs.IFC.GetAttributeDto<IfcModel>): Inputs.IFC.IfcAttributeValue;
228
+ /**
229
+ * Says which GlobalId an id stands for in a model: the GlobalId itself, or the one the model
230
+ * derives from an id of your own such as `north-wall`.
231
+ *
232
+ * The answer does not depend on whether the model holds such an object yet.
233
+ * @param inputs - The model and the id
234
+ * @returns The GlobalId, 22 characters
235
+ * @group query
236
+ * @shortname global id of
237
+ * @drawable false
238
+ * @example
239
+ * ```typescript
240
+ * const globalId = await bitbybit.ifc.model.globalIdOf({ model, id: "north-wall" });
241
+ * ```
242
+ */
243
+ globalIdOf(inputs: Inputs.IFC.GlobalIdOfDto<IfcModel>): string;
244
+ }