diff --git a/src/elements/CurtainWalls/SimpleCurtainWall/index.html b/src/elements/CurtainWalls/SimpleCurtainWall/index.html
new file mode 100644
index 0000000..96380be
--- /dev/null
+++ b/src/elements/CurtainWalls/SimpleCurtainWall/index.html
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+
+
+
+ Tools Component
+
+
+
+
+
+
+
+
diff --git a/src/elements/CurtainWalls/SimpleCurtainWall/index.ts b/src/elements/CurtainWalls/SimpleCurtainWall/index.ts
new file mode 100644
index 0000000..c3f135e
--- /dev/null
+++ b/src/elements/CurtainWalls/SimpleCurtainWall/index.ts
@@ -0,0 +1,398 @@
+import { IFC4X3, IFC4X3 as IFC } from "web-ifc";
+import { v4 as uuidv4 } from "uuid";
+import { Model } from "../../../base";
+import { IfcUtils } from "../../../utils/ifc-utils";
+import { StaticElementType } from "../../Elements";
+import { SimpleCurtainWall } from "./src";
+import { SimpleMemberType } from "../../Members";
+import { SimplePlateType } from "../../Plates";
+import { SimpleMember } from "../../Members/SimpleMember/src";
+import { SimplePlate } from "../../Plates/SimplePlate/src";
+import * as THREE from "three";
+
+export * from "./src";
+
+export class SimpleCurtainWallType extends StaticElementType {
+ attributes: IFC4X3.IfcCurtainWallType;
+
+ shape: IFC4X3.IfcProductDefinitionShape;
+
+ height = 3;
+
+ frameWidth = 0.127;
+
+ startPoint = new THREE.Vector3(0,0,0)
+
+ endPoint = new THREE.Vector3(1,0,0)
+
+ numberOfColumns = 2;
+
+ numberOfRows = 2;
+
+ private plates: SimplePlate[] = [];
+
+ private sideAMembers: SimpleMember[] = [];
+
+ private sideBMembers: SimpleMember[] = [];
+
+ private bottomMembers: SimpleMember[] = [];
+
+ private topMembers: SimpleMember[] = [];
+
+ private middleHorizontalMembers: SimpleMember[] = [];
+
+ private middleVerticalMembers: SimpleMember[] = [];
+
+ get length() {
+ return this.startPoint.distanceTo(this.endPoint);
+ }
+
+ get midPoint() {
+ return new THREE.Vector3(
+ (this.startPoint.x + this.endPoint.x) / 2,
+ (this.startPoint.y + this.endPoint.y) / 2,
+ (this.startPoint.z + this.endPoint.z) / 2
+ );
+ }
+
+ get direction() {
+ const vector = new THREE.Vector3();
+ vector.subVectors(this.endPoint, this.startPoint);
+ vector.normalize();
+ return vector;
+ }
+
+ constructor(model: Model, numberOfColumns?: number, numberOfRows?: number) {
+ super(model);
+
+ if (numberOfColumns)
+ this.numberOfColumns = numberOfColumns;
+
+ if (numberOfRows)
+ this.numberOfRows = numberOfRows;
+
+ const componentAttributes = this.instantiateComponents(model);
+
+ this.shape = IfcUtils.productDefinitionShape(model, componentAttributes);
+
+ this.attributes = new IFC.IfcCurtainWallType(
+ new IFC.IfcGloballyUniqueId(uuidv4()),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ IFC.IfcCurtainWallTypeEnum.NOTDEFINED
+ );
+
+ this.updateComponentGeometries();
+ this.model.set(this.attributes);
+ }
+
+ update(updateGeometry: boolean = false) {
+ this.updateComponentGeometries();
+ super.update(updateGeometry);
+ }
+
+ instantiateComponents(model: Model = this.model) {
+ console.log('intantiating...')
+ for (let currentColumn = 0; currentColumn < this.numberOfColumns; currentColumn++) {
+
+ const bottomMember = new SimpleMemberType(model).addInstance();
+ const bottomMemberId = bottomMember.body.attributes.expressID;
+ this.fragments.set(bottomMemberId, this.newFragment());
+ this.geometries.set(bottomMemberId, bottomMember.body);
+ this.bottomMembers.push(bottomMember);
+
+ for (let currentRow = 0; currentRow < this.numberOfRows; currentRow++) {
+
+ if (currentColumn == 0) {
+ const sideAMember = new SimpleMemberType(model).addInstance();
+ const sideAMemberId = sideAMember.body.attributes.expressID;
+ this.fragments.set(sideAMemberId, this.newFragment());
+ this.geometries.set(sideAMemberId, sideAMember.body);
+ this.sideAMembers.push(sideAMember);
+ }
+
+ if (currentRow > 0) {
+ const middleHorizontalMember = new SimpleMemberType(model).addInstance();
+ const middleHorizontalMemberId = middleHorizontalMember.body.attributes.expressID;
+ this.fragments.set(middleHorizontalMemberId, this.newFragment());
+ this.geometries.set(middleHorizontalMemberId, middleHorizontalMember.body);
+ this.middleHorizontalMembers.push(middleHorizontalMember);
+ }
+
+ if (currentColumn > 0) {
+ const middleVerticalMember = new SimpleMemberType(model).addInstance();
+ const middleVerticalMemberId = middleVerticalMember.body.attributes.expressID;
+ this.fragments.set(middleVerticalMemberId, this.newFragment());
+ this.geometries.set(middleVerticalMemberId, middleVerticalMember.body);
+ this.middleVerticalMembers.push(middleVerticalMember);
+ }
+
+ if (currentColumn == this.numberOfColumns - 1) {
+ const sideBMember = new SimpleMemberType(model).addInstance();
+ const sideBMemberId = sideBMember.body.attributes.expressID;
+ this.fragments.set(sideBMemberId, this.newFragment());
+ this.geometries.set(sideBMemberId, sideBMember.body);
+ this.sideBMembers.push(sideBMember);
+ }
+
+ const plate = new SimplePlateType(model).addInstance();
+ const plateId = plate.body.attributes.expressID;
+ this.fragments.set(plateId, this.newFragment());
+ this.geometries.set(plateId, plate.body);
+ this.plates.push(plate);
+ }
+ const topMember = new SimpleMemberType(model).addInstance();
+ const topMemberId = topMember.body.attributes.expressID;
+ this.fragments.set(topMemberId, this.newFragment());
+ this.geometries.set(topMemberId, topMember.body);
+ this.topMembers.push(topMember);
+ }
+
+ const components = new Array().concat(
+ this.plates,
+ this.sideAMembers,
+ this.sideBMembers,
+ this.bottomMembers,
+ this.topMembers,
+ this.middleHorizontalMembers,
+ this.middleVerticalMembers
+ );
+
+ return components.map((component) => component.body.attributes);
+ }
+
+// updateComponentGeometries(model: Model = this.model) {
+// const memberWidth = new SimpleMemberType(model).addInstance().width;
+// const plateWidth = this.length / this.numberOfColumns - memberWidth;
+// const plateHeight = (this.height - (this.numberOfRows + 1) * memberWidth) / this.numberOfRows;
+// const deltaX = (this.endPoint.x - this.startPoint.x) / this.numberOfColumns;
+// const deltaY = (this.endPoint.y - this.startPoint.y) / this.numberOfColumns;
+// const rotationY = Math.atan2(this.endPoint.x - this.startPoint.x, this.endPoint.y - this.startPoint.y);
+
+// for (let currentColumn = 0; currentColumn < this.numberOfColumns; currentColumn++) {
+// const posX = this.startPoint.x + currentColumn * deltaX;
+// const posY = this.startPoint.y + currentColumn * deltaY;
+
+// const bottomMember = this.bottomMembers[currentColumn];
+// bottomMember.body.profile.dimension.x = this.frameWidth;
+// bottomMember.body.depth = this.length / this.numberOfColumns;
+// bottomMember.body.position.set(posX, posY, memberWidth / 2);
+// bottomMember.body.rotation.set(Math.PI / -2, rotationY, 0);
+// bottomMember.body.profile.update();
+// bottomMember.body.update();
+
+// for (let currentRow = 0; currentRow < this.numberOfRows; currentRow++) {
+// const nonInitialVerticalRowLocation = memberWidth + currentRow * (plateHeight + memberWidth);
+
+// if (currentColumn == 0) {
+// const sideAMember = this.sideAMembers[currentRow];
+// console.log(currentRow)
+// console.log(this.sideAMembers)
+// console.log('here!!!!!!!!!!!!!!!!!!!')
+// sideAMember.body.profile.dimension.x = this.frameWidth;
+// sideAMember.body.profile.position.y = memberWidth/2
+// sideAMember.body.depth = plateHeight;
+// sideAMember.body.position.set(this.startPoint.x, this.startPoint.y, currentRow > 0 ? nonInitialVerticalRowLocation : memberWidth);
+// sideAMember.body.rotation.set(0, 0, -rotationY);
+// sideAMember.body.profile.update();
+// sideAMember.body.update();
+// }
+
+// if (currentColumn == this.numberOfColumns - 1) {
+// const sideBMember = this.sideBMembers[currentRow];
+// sideBMember.body.profile.dimension.x = this.frameWidth;
+// sideBMember.body.profile.position.y = -1 * (memberWidth/2)
+// sideBMember.body.depth = plateHeight;
+// sideBMember.body.position.set(this.endPoint.x, this.endPoint.y, currentRow > 0 ? nonInitialVerticalRowLocation : memberWidth);
+// sideBMember.body.rotation.set(0, 0, -rotationY);
+// sideBMember.body.profile.update();
+// sideBMember.body.update();
+// }
+
+// if (currentRow > 0) {
+// const middleHorizontalMember = this.middleHorizontalMembers[currentColumn * (this.numberOfRows - 1) + (currentRow - 1)];
+// middleHorizontalMember.body.profile.dimension.x = this.frameWidth;
+// middleHorizontalMember.body.depth = this.length / this.numberOfColumns;
+// middleHorizontalMember.body.position.set(posX, posY, nonInitialVerticalRowLocation - memberWidth / 2);
+// middleHorizontalMember.body.rotation.set(Math.PI / -2, rotationY, 0);
+// middleHorizontalMember.body.profile.update();
+// middleHorizontalMember.body.update();
+// }
+
+// if (currentColumn > 0 && currentRow < this.numberOfRows) {
+// const middleVerticalMember = this.middleVerticalMembers[(currentColumn - 1) * this.numberOfRows + currentRow];
+// middleVerticalMember.body.profile.dimension.x = this.frameWidth;
+// middleVerticalMember.body.depth = plateHeight;
+// middleVerticalMember.body.position.set(posX, posY, currentRow > 0 ? nonInitialVerticalRowLocation : memberWidth);
+// middleVerticalMember.body.rotation.set(0, 0, -rotationY);
+// middleVerticalMember.body.profile.update();
+// middleVerticalMember.body.update();
+// }
+
+// const plate = this.plates[currentColumn * this.numberOfRows + currentRow];
+// plate.body.profile.dimension.y = plateWidth;
+// plate.body.depth = plateHeight;
+// plate.body.position.set(posX + deltaX / 2, posY + deltaY / 2, currentRow > 0 ? nonInitialVerticalRowLocation : memberWidth);
+// plate.body.rotation.z = -rotationY;
+// plate.body.profile.update();
+// plate.body.update();
+// }
+
+// const topMember = this.topMembers[currentColumn];
+// topMember.body.profile.dimension.x = this.frameWidth;
+// topMember.body.depth = this.length / this.numberOfColumns;
+// topMember.body.position.set(posX, posY, this.height - memberWidth / 2);
+// topMember.body.rotation.set(Math.PI / -2, rotationY, 0);
+// topMember.body.profile.update();
+// topMember.body.update();
+// }
+// }
+
+updateComponentGeometries(model: Model = this.model) {
+
+ const memberWidth = new SimpleMemberType(model).addInstance().width;
+ const plateWidth = this.length/this.numberOfColumns - memberWidth;
+ const plateHeight = (this.height - (this.numberOfRows + 1) * memberWidth) / this.numberOfRows;
+
+ for (let currentColumn = 0; currentColumn < this.numberOfColumns; currentColumn++) {
+
+ const bottomMember = this.bottomMembers[currentColumn];
+ bottomMember.body.profile.dimension.x = this.frameWidth;
+ bottomMember.body.depth = this.length / this.numberOfColumns;
+ bottomMember.body.position.x = this.startPoint.x + (currentColumn/this.numberOfColumns) * (this.endPoint.x - this.startPoint.x);
+ bottomMember.body.position.y = this.startPoint.y + (currentColumn/this.numberOfColumns) * (this.endPoint.y - this.startPoint.y);
+ bottomMember.body.position.z = memberWidth / 2;
+ bottomMember.body.rotation.x = Math.PI / -2;
+ bottomMember.body.rotation.y = Math.atan2(this.endPoint.x -this.startPoint.x, this.endPoint.y - this.startPoint.y);
+
+ if (currentColumn == this.numberOfColumns - 1) {
+ bottomMember.body.depth = this.length / this.numberOfColumns;
+ }
+
+ bottomMember.body.profile.update();
+ bottomMember.body.update();
+
+ for (let currentRow = 0; currentRow < this.numberOfRows; currentRow++) {
+
+ const nonInitialVerticalRowLocation = memberWidth + currentRow * (plateHeight + memberWidth);
+
+ if (currentColumn == 0) {
+
+ const sideAMember = this.sideAMembers[currentRow]
+ sideAMember.body.profile.dimension.x = this.frameWidth;
+ sideAMember.body.profile.position.y = memberWidth/2
+ sideAMember.body.depth = plateHeight;
+ sideAMember.body.position.x = this.startPoint.x;
+ sideAMember.body.position.y = this.startPoint.y;
+ sideAMember.body.position.z = memberWidth;
+ sideAMember.body.rotation.z = -1 * Math.atan2(this.endPoint.x -this.startPoint.x, this.endPoint.y - this.startPoint.y);
+
+ if (currentRow > 0) {
+ sideAMember.body.position.z = nonInitialVerticalRowLocation;
+ }
+
+ sideAMember.body.profile.update();
+ sideAMember.body.update();
+ }
+
+ if (currentRow > 0) {
+
+ const middleHorizontalMember = this.middleHorizontalMembers[currentColumn * (this.numberOfRows - 1) + (currentRow - 1)]
+ middleHorizontalMember.body.profile.dimension.x = this.frameWidth;
+ middleHorizontalMember.body.depth = this.length / this.numberOfColumns;
+ middleHorizontalMember.body.position.x = this.startPoint.x + (currentColumn/this.numberOfColumns) * (this.endPoint.x - this.startPoint.x);
+ middleHorizontalMember.body.position.y = this.startPoint.y + (currentColumn/this.numberOfColumns) * (this.endPoint.y - this.startPoint.y);
+ middleHorizontalMember.body.position.z = nonInitialVerticalRowLocation - memberWidth / 2;
+ middleHorizontalMember.body.rotation.x = Math.PI / -2;
+ middleHorizontalMember.body.rotation.y = Math.atan2(this.endPoint.x -this.startPoint.x, this.endPoint.y - this.startPoint.y);
+
+ middleHorizontalMember.body.profile.update();
+ middleHorizontalMember.body.update();
+ }
+
+ if (currentColumn > 0) {
+
+ const middleVerticalMember = this.middleVerticalMembers[(currentColumn - 1) * this.numberOfRows + currentRow]
+ middleVerticalMember.body.profile.dimension.x = this.frameWidth;
+ middleVerticalMember.body.depth = plateHeight;
+ middleVerticalMember.body.position.x = this.startPoint.x + (currentColumn/this.numberOfColumns) * (this.endPoint.x - this.startPoint.x);
+ middleVerticalMember.body.position.y = this.startPoint.y + (currentColumn/this.numberOfColumns) * (this.endPoint.y - this.startPoint.y);
+ middleVerticalMember.body.position.z = memberWidth;
+ middleVerticalMember.body.rotation.z = -1 * Math.atan2(this.endPoint.x -this.startPoint.x, this.endPoint.y - this.startPoint.y);
+
+ if (currentRow > 0) {
+ middleVerticalMember.body.position.z = nonInitialVerticalRowLocation;
+ }
+ middleVerticalMember.body.profile.update();
+ middleVerticalMember.body.update();
+ }
+
+
+ if (currentColumn == this.numberOfColumns - 1) {
+
+ const sideBMember = this.sideBMembers[currentRow]
+ sideBMember.body.profile.position.y = -1 * (memberWidth/2)
+ sideBMember.body.profile.dimension.x = this.frameWidth;
+ sideBMember.body.depth = plateHeight;
+ sideBMember.body.position.x = this.endPoint.x;
+ sideBMember.body.position.y = this.endPoint.y
+ sideBMember.body.position.z = memberWidth;
+ sideBMember.body.rotation.z = -1 * Math.atan2(this.endPoint.x -this.startPoint.x, this.endPoint.y - this.startPoint.y);
+
+ if (currentRow > 0) {
+ sideBMember.body.position.z = nonInitialVerticalRowLocation;
+ }
+
+ sideBMember.body.profile.update();
+ sideBMember.body.update();
+ }
+
+ const plate = this.plates[currentColumn * this.numberOfRows + currentRow];
+ plate.body.profile.dimension.y = plateWidth;
+ plate.body.depth = plateHeight;
+ plate.body.position.z = memberWidth;
+ plate.body.position.x = this.startPoint.x + (((this.endPoint.x - this.startPoint.x)/this.numberOfColumns) /2) + ((currentColumn/this.numberOfColumns) * (this.endPoint.x - this.startPoint.x )) ;
+ plate.body.position.y = this.startPoint.y + (((this.endPoint.y - this.startPoint.y)/this.numberOfColumns) /2) + ((currentColumn/this.numberOfColumns) * (this.endPoint.y - this.startPoint.y )) ;
+ plate.body.rotation.z = -1 * Math.atan2(this.endPoint.x -this.startPoint.x, this.endPoint.y - this.startPoint.y);
+
+ if (currentRow > 0) {
+ plate.body.position.z = nonInitialVerticalRowLocation;
+ }
+
+ if (currentColumn == 0 || currentColumn == this.numberOfColumns - 1)
+ {
+ plate.body.profile.dimension.y = plateWidth - memberWidth/2
+ plate.body.profile.position.y = memberWidth/4
+ }
+
+ if (currentColumn == this.numberOfColumns - 1) {
+ plate.body.profile.position.y = -memberWidth/4
+ }
+
+ plate.body.profile.update();
+ plate.body.update();
+ }
+
+ const topMember = this.topMembers[currentColumn]
+ topMember.body.profile.dimension.x = this.frameWidth;
+ topMember.body.depth = this.length / this.numberOfColumns;
+ topMember.body.position.x = this.startPoint.x + (currentColumn/this.numberOfColumns) * (this.endPoint.x - this.startPoint.x);
+ topMember.body.position.y = this.startPoint.y + (currentColumn/this.numberOfColumns) * (this.endPoint.y - this.startPoint.y);
+ topMember.body.position.z = this.height - memberWidth / 2;
+ topMember.body.rotation.x = Math.PI / -2;
+ topMember.body.rotation.y = Math.atan2(this.endPoint.x -this.startPoint.x, this.endPoint.y - this.startPoint.y);
+
+ topMember.body.profile.update();
+ topMember.body.update();
+ }
+}
+ protected createElement() {
+ return new SimpleCurtainWall(this.model, this);
+ }
+}
diff --git a/src/elements/CurtainWalls/SimpleCurtainWall/src/index.ts b/src/elements/CurtainWalls/SimpleCurtainWall/src/index.ts
new file mode 100644
index 0000000..e6a9db2
--- /dev/null
+++ b/src/elements/CurtainWalls/SimpleCurtainWall/src/index.ts
@@ -0,0 +1,37 @@
+import { IFC4X3 as IFC } from "web-ifc";
+import { v4 as uuidv4 } from "uuid";
+import { Model } from "../../../../base";
+import { IfcUtils } from "../../../../utils/ifc-utils";
+import { Element } from "../../../Elements/Element";
+import { SimpleCurtainWallType } from "../index";
+
+export class SimpleCurtainWall extends Element {
+ attributes: IFC.IfcCurtainWall;
+
+ type: SimpleCurtainWallType;
+
+ constructor(model: Model, type: SimpleCurtainWallType) {
+ super(model, type);
+ this.type = type;
+
+ const placement = IfcUtils.localPlacement();
+
+ for (const [id] of type.geometries) {
+ this.geometries.add(id);
+ }
+
+ this.attributes = new IFC.IfcCurtainWall(
+ new IFC.IfcGloballyUniqueId(uuidv4()),
+ null,
+ null,
+ null,
+ null,
+ placement,
+ type.shape,
+ null,
+ null
+ );
+
+ this.model.set(this.attributes);
+ }
+}
diff --git a/src/elements/CurtainWalls/index.ts b/src/elements/CurtainWalls/index.ts
new file mode 100644
index 0000000..c4c1f4b
--- /dev/null
+++ b/src/elements/CurtainWalls/index.ts
@@ -0,0 +1 @@
+export * from "./SimpleCurtainWall"
\ No newline at end of file
diff --git a/src/elements/Members/SimpleMember/index.html b/src/elements/Members/SimpleMember/index.html
new file mode 100644
index 0000000..81f2aef
--- /dev/null
+++ b/src/elements/Members/SimpleMember/index.html
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+ Tools Component
+
+
+
+
+
+
+
+
diff --git a/src/elements/Members/SimpleMember/index.ts b/src/elements/Members/SimpleMember/index.ts
new file mode 100644
index 0000000..bd63d33
--- /dev/null
+++ b/src/elements/Members/SimpleMember/index.ts
@@ -0,0 +1,34 @@
+import { v4 as uuidv4 } from "uuid";
+import { IFC4X3 as IFC } from "web-ifc";
+import { Model } from "../../../base";
+import { DynamicElementType } from "../../Elements";
+import { SimpleMember } from "./src";
+
+export class SimpleMemberType extends DynamicElementType {
+ attributes: IFC.IfcMemberType;
+
+ memberType: IFC.IfcMemberTypeEnum
+
+ constructor(model: Model) {
+ super(model);
+
+ this.memberType = IFC.IfcMemberTypeEnum.MULLION
+
+ this.attributes = new IFC.IfcMemberType(
+ new IFC.IfcGloballyUniqueId(uuidv4()),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ this.memberType,
+ );
+ }
+
+ protected createElement() {
+ return new SimpleMember(this.model, this);
+ }
+}
diff --git a/src/elements/Members/SimpleMember/src/index.ts b/src/elements/Members/SimpleMember/src/index.ts
new file mode 100644
index 0000000..16fec2f
--- /dev/null
+++ b/src/elements/Members/SimpleMember/src/index.ts
@@ -0,0 +1,51 @@
+import { IFC4X3 as IFC } from "web-ifc";
+import { Element } from "../../../Elements";
+import { Model } from "../../../../base";
+import { SimpleMemberType } from "..";
+import { v4 as uuidv4 } from "uuid";
+import { IfcUtils } from "../../../../utils/ifc-utils";
+import { Extrusion, RectangleProfile } from "../../../../geometries";
+import * as THREE from "three";
+
+export class SimpleMember extends Element {
+ attributes: IFC.IfcMember;
+
+ body: Extrusion;
+
+ type: SimpleMemberType;
+
+ width = 0.0635;
+
+ depth = 0.127;
+
+ constructor(model: Model, type: SimpleMemberType) {
+ super(model, type);
+ this.type = type;
+ const location = new THREE.Vector3(0, 0, 1);
+ const placement = IfcUtils.localPlacement(location);
+
+ const profile = new RectangleProfile(model);
+ profile.dimension.x = this.depth;
+ profile.dimension.y = this.width;
+ profile.position = new THREE.Vector3(0, 0, 5);
+ profile.update();
+
+ this.body = new Extrusion(model, profile);
+ const id = this.body.attributes.expressID;
+ this.type.geometries.set(id, this.body);
+ this.geometries.add(id);
+
+ this.attributes = new IFC.IfcPlate(
+ new IFC.IfcGloballyUniqueId(uuidv4()),
+ null,
+ null,
+ null,
+ null,
+ placement,
+ IfcUtils.productDefinitionShape(model, [this.body.attributes]),
+ null,
+ type.memberType
+ );
+ this.model.set(this.attributes);
+ }
+}
diff --git a/src/elements/Members/index.ts b/src/elements/Members/index.ts
new file mode 100644
index 0000000..816f875
--- /dev/null
+++ b/src/elements/Members/index.ts
@@ -0,0 +1 @@
+export * from "./SimpleMember"
\ No newline at end of file
diff --git a/src/elements/Plates/SimplePlate/index.html b/src/elements/Plates/SimplePlate/index.html
new file mode 100644
index 0000000..db25820
--- /dev/null
+++ b/src/elements/Plates/SimplePlate/index.html
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+ Tools Component
+
+
+
+
+
+
+
+
diff --git a/src/elements/Plates/SimplePlate/index.ts b/src/elements/Plates/SimplePlate/index.ts
new file mode 100644
index 0000000..3eff71a
--- /dev/null
+++ b/src/elements/Plates/SimplePlate/index.ts
@@ -0,0 +1,34 @@
+import { v4 as uuidv4 } from "uuid";
+import { IFC4X3 as IFC } from "web-ifc";
+import { Model } from "../../../base";
+import { DynamicElementType } from "../../Elements";
+import { SimplePlate } from "./src";
+
+export class SimplePlateType extends DynamicElementType {
+ attributes: IFC.IfcPlateType;
+
+ plateType: IFC.IfcPlateTypeEnum
+
+ constructor(model: Model) {
+ super(model);
+
+ this.plateType = IFC.IfcPlateTypeEnum.CURTAIN_PANEL
+
+ this.attributes = new IFC.IfcPlateType(
+ new IFC.IfcGloballyUniqueId(uuidv4()),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ this.plateType,
+ );
+ }
+
+ protected createElement() {
+ return new SimplePlate(this.model, this);
+ }
+}
diff --git a/src/elements/Plates/SimplePlate/src/index.ts b/src/elements/Plates/SimplePlate/src/index.ts
new file mode 100644
index 0000000..c28ccfc
--- /dev/null
+++ b/src/elements/Plates/SimplePlate/src/index.ts
@@ -0,0 +1,51 @@
+import { IFC4X3 as IFC } from "web-ifc";
+import { Element } from "../../../Elements";
+import { Model } from "../../../../base";
+import { SimplePlateType } from "..";
+import { v4 as uuidv4 } from "uuid";
+import { IfcUtils } from "../../../../utils/ifc-utils";
+import { Extrusion, RectangleProfile } from "../../../../geometries";
+import * as THREE from "three";
+
+export class SimplePlate extends Element {
+ attributes: IFC.IfcPlate;
+
+ body: Extrusion;
+
+ type: SimplePlateType
+
+ constructor(model: Model, type: SimplePlateType) {
+ super(model, type)
+ this.type = type
+
+ const placement = IfcUtils.localPlacement();
+
+ const profile = new RectangleProfile(model);
+ profile.dimension.x = 0.0833333333333333
+ profile.dimension.y = 1.9238
+ profile.dimension.z = 1
+ profile.position = new THREE.Vector3(0,0,0)
+ profile.update();
+
+ this.body = new Extrusion(model, profile);
+ const id = this.body.attributes.expressID;
+ this.type.geometries.set(id, this.body);
+ this.geometries.add(id);
+
+
+ this.attributes = new IFC.IfcPlate(
+ new IFC.IfcGloballyUniqueId(uuidv4()),
+ null,
+ null,
+ null,
+ null,
+ placement,
+ IfcUtils.productDefinitionShape(model, [this.body.attributes]),
+ null,
+ type.plateType,
+ )
+
+ this.model.set(this.attributes);
+ }
+
+}
diff --git a/src/elements/Plates/index.ts b/src/elements/Plates/index.ts
new file mode 100644
index 0000000..201ae88
--- /dev/null
+++ b/src/elements/Plates/index.ts
@@ -0,0 +1 @@
+export * from "./SimplePlate";
diff --git a/src/elements/index.ts b/src/elements/index.ts
index 4ee9c41..1220c68 100644
--- a/src/elements/index.ts
+++ b/src/elements/index.ts
@@ -3,3 +3,6 @@ export * from "./Slabs";
export * from "./Walls";
export * from "./Furniture";
export * from "./Windows";
+export * from "./Plates"
+export * from "./Members"
+export * from "./CurtainWalls"
diff --git a/src/geometries/Profiles/RectangleProfile/index.ts b/src/geometries/Profiles/RectangleProfile/index.ts
index 360c5cd..e6be4b3 100644
--- a/src/geometries/Profiles/RectangleProfile/index.ts
+++ b/src/geometries/Profiles/RectangleProfile/index.ts
@@ -12,6 +12,8 @@ export class RectangleProfile extends Profile {
rotation = new THREE.Euler(0, 0, 0);
position = new THREE.Vector3(0, 0, 0);
+
+ depth = 1;
constructor(model: Model) {
super(model);
@@ -36,6 +38,11 @@ export class RectangleProfile extends Profile {
this.attributes.XDim.value = this.dimension.x;
this.attributes.YDim.value = this.dimension.y;
+ this.attributes.Position = new IFC.IfcAxis2Placement2D(
+ IfcUtils.point(this.position),
+ IfcUtils.direction(new THREE.Vector3(1, 0, 0))
+ );
+
const placement = this.model.get(this.attributes.Position);
IfcUtils.setAxis2Placement(