Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
wojciechteclaw committed Jan 16, 2024
2 parents f2a8e98 + cde4a38 commit e6e59ac
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 11 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/node_modules/
.vscode/
/dist/
*.d.ts
*.d.ts
.idea
3 changes: 2 additions & 1 deletion public/assets/example_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"body": "Site",
"prefix": "bot:",
"label": "bot:Site"
}
},
"position": { "x": 100, "y": 100 }
},
{
"data": {
Expand Down
2 changes: 1 addition & 1 deletion src/components/graph/Graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const Graph: FC<GraphProps> = ({ graphElements, setCyReference }) => {
cyRef.current.elements().remove();
cyRef.current.add(graphElements);
cyRef.current.layout(graphLayoutConfiguration).run();
cyRef.current.fit();
// cyRef.current.fit();
}
}, [graphElements]);

Expand Down
1 change: 0 additions & 1 deletion src/components/graph_container/GraphContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const GraphContainer: FC = () => {
if (result) {
let parser = new SparQlGraphParserService(result);
let results = parser.convertQueryResultToGraphInput();
console.log(results)
setGraphElements(results);
}
};
Expand Down
5 changes: 2 additions & 3 deletions src/helpers/elements_comparison.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { ConnectorFlowDirection } from "@enums/connector_flow_direction";
class ElementsComparison {
private static ANGLE_TOLERANCE = 1;
// milimeters
private static DISTANCE_TOLERANCE = 25;
private static DISTANCE_TOLERANCE = 0.025;

public static async compareElements(
elements1: IfcElement[],
Expand Down Expand Up @@ -54,7 +54,7 @@ class ElementsComparison {
element2.representation as ConnectorRepresentation
)
) {
return this.buildNewConnectorsConnection(element1, element2, connections);
this.buildNewConnectorsConnection(element1, element2, connections);
}
}
}
Expand Down Expand Up @@ -86,7 +86,6 @@ class ElementsComparison {
element2: ConnectorRepresentation
): boolean {
const distance = element1.connector.location.distanceTo(element2.connector.location);
console.log(distance);
if (
distance > this.DISTANCE_TOLERANCE ||
!GeometryOperations.areVectorsParallel(
Expand Down
1 change: 1 addition & 0 deletions src/helpers/file_operations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class FileOperations {
public static async getFileBuffer(file: File): Promise<Uint8Array> {

let fileBuffer = await this.readInputFile(file);
return new Uint8Array(fileBuffer);
}
Expand Down
1 change: 1 addition & 0 deletions src/helpers/semantic_operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class SemanticOperations {
break;
case Connection.CONNECTED_PORT:
connectionSpecificTriples = this.generateTriplesForMepElements(connection);
console.log(connectionSpecificTriples)
break;
default:
break;
Expand Down
2 changes: 1 addition & 1 deletion src/services/connectors_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,4 @@ class ConnectorsManager {
}
}

export { ConnectorsManager }
export { ConnectorsManager };
175 changes: 175 additions & 0 deletions src/services/element-placement.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { Matrix4, Vector3, Quaternion } from "three";
import {
IfcAPI,
IFCDISTRIBUTIONPORT,
IFCFLOWSEGMENT,
IFCFLOWFITTING,
IFCFLOWTERMINAL,
IFCLOCALPLACEMENT,
IFCAXIS2PLACEMENT3D,
IFCRELCONNECTSPORTTOELEMENT,
} from "web-ifc";

type ElementLocation = {
guid: number;
location: Vector3;
};

type IfcElementToPort = {
elementID: string;
portID: string;
};

export class ElementPlacementService {
private queryCache: { [modelID: number]: { [expressId: number]: Matrix4 } } = { 0: {} };
private ifcAPI: IfcAPI;

constructor(ifcAPI: IfcAPI) {
this.ifcAPI = ifcAPI;
}

public async getElementsCoordinates(modelID: number) {
this.queryCache[modelID] = {};
const elementClasses = [IFCDISTRIBUTIONPORT, IFCFLOWFITTING, IFCFLOWTERMINAL];
const promisesOfElements: Promise<ElementLocation>[] = [];
const promisesOfRelations: Promise<IfcElementToPort>[] = [];
const elements = {};
for (const ifcClass of elementClasses) {
const elements = this.ifcAPI.GetLineIDsWithType(modelID, ifcClass);
const elementsNumber = elements.size();
for (let i = 0; i < elementsNumber; i++) {
const expressID = elements.get(i);
promisesOfElements.push(this.getElementLocation(modelID, expressID));
}
}
const portToElementRelations = this.ifcAPI.GetLineIDsWithType(modelID, IFCRELCONNECTSPORTTOELEMENT);
const numberOfRelations = portToElementRelations.size();
for (let i = 0; i < numberOfRelations; i++) {
const expressID = portToElementRelations.get(i);
promisesOfRelations.push(this.getIfcElementToPortRelation(modelID, expressID));
}
await Promise.all(promisesOfElements).then((elementsLocation) => {
for (const element of elementsLocation) {
elements[element.guid] = element.location;
}
});
const ifcElementPortRelations = {};
await Promise.all(promisesOfRelations).then((r) => {
for (const relation of r) {
if (!ifcElementPortRelations[relation.elementID]) {
ifcElementPortRelations[relation.elementID] = [relation.portID];
} else {
ifcElementPortRelations[relation.elementID].push(relation.portID);
}
}
});
this.getSegmentsCoordinates(modelID, elements, ifcElementPortRelations);
console.log(elements);
}

private getSegmentsCoordinates(modelID: number, elements, ifcElementPortRelations) {
const segments = this.ifcAPI.GetLineIDsWithType(modelID, IFCFLOWSEGMENT);
for (let i = 0; i < segments.size(); i++) {
const segmentExpressID = segments.get(i);
const segmentElement = this.ifcAPI.GetLine(modelID, segmentExpressID);
const relatedPorts = ifcElementPortRelations[segmentElement.GlobalId.value];
const x = (elements[relatedPorts[0]].x + elements[relatedPorts[1]].x) / 2;
const y = (elements[relatedPorts[0]].y + elements[relatedPorts[1]].y) / 2;
const z = (elements[relatedPorts[0]].z + elements[relatedPorts[1]].z) / 2;
elements[segmentElement.GlobalId.value] = new Vector3(x, y, z);
}
}

private async getIfcElementToPortRelation(modelID: number, expressID: number): Promise<IfcElementToPort> {
const element = this.ifcAPI.GetLine(modelID, expressID);
const portElement = this.ifcAPI.GetLine(modelID, element.RelatingPort.value);
const ifcElement = this.ifcAPI.GetLine(modelID, element.RelatedElement.value);
return {
elementID: ifcElement.GlobalId.value,
portID: portElement.GlobalId.value,
};
}

private async getElementLocation(modelID: number, expressID: number): Promise<ElementLocation> {
const element = this.ifcAPI.GetLine(modelID, expressID);
const location = await this.getPlacementCharacteristic(modelID, element);
return {
guid: element.GlobalId.value,
location: location,
};
}

private async getPlacementCharacteristic(modelID, port: any): Promise<Vector3> {
const portPlacement = this.ifcAPI.GetLine(modelID, port.ObjectPlacement.value);
const globalTransformation = this.getTransformationMatrix(modelID, portPlacement.PlacementRelTo.value);
const translation = new Matrix4().copyPosition(globalTransformation);
globalTransformation.setPosition(new Vector3(0, 0, 0));
const location = this.getPortNormalAndLocation(modelID, portPlacement);
location.applyMatrix4(globalTransformation).applyMatrix4(translation);
return location;
}

private getPortNormalAndLocation(modelID: number, placement): Vector3 {
const localPlacement = this.ifcAPI.GetLine(modelID, placement.RelativePlacement.value);
const location = this.ifcAPI.GetLine(modelID, localPlacement.Location.value)["Coordinates"];
return new Vector3(location[0].value, location[1].value, location[2].value);
}

private placementMatrix(modelID: number, placement: any): Matrix4 {
if (placement !== null) {
if (this.queryCache[modelID][placement.value]) {
return new Matrix4().copy(this.queryCache[modelID][placement.value]);
}
const localItem = placement.value;
const result = this.getTransformationMatrix(modelID, localItem);
this.queryCache[modelID][localItem] = new Matrix4().copy(result);
return result;
}
return new Matrix4().identity();
}

private getVector(
line: any,
modelID: number,
lineParameter: string,
lineProperty: string,
defaultVector: Vector3
): Vector3 {
if (line[`${lineParameter}`] !== null) {
const result = this.ifcAPI.GetLine(modelID, line[`${lineParameter}`].value)[`${lineProperty}`];
defaultVector.set(result[0].value, result[1].value, result[2].value);
}
return defaultVector;
}

private getTransformationMatrix(modelID: number, expressID: number): Matrix4 {
const line = this.ifcAPI.GetLine(modelID, expressID);
switch (line.type) {
case IFCLOCALPLACEMENT:
const global = this.placementMatrix(modelID, line.PlacementRelTo);
const local = this.placementMatrix(modelID, line.RelativePlacement);
const result = local.multiply(global);
return result;
case IFCAXIS2PLACEMENT3D:
const xAxis = this.getVector(line, modelID, "RefDirection", "DirectionRatios", new Vector3(1, 0, 0));
const zAxis = this.getVector(line, modelID, "Axis", "DirectionRatios", new Vector3(0, 0, 1));
const point = this.getVector(line, modelID, "Location", "Coordinates", new Vector3(0, 0, 0));
return ElementPlacementService.buildTransformationMatrix(point, xAxis, zAxis);
default:
return new Matrix4().identity();
}
}

private static buildTransformationMatrix(
point: Vector3 = new Vector3(0, 0, 0),
xAxis: Vector3 = new Vector3(1, 0, 0),
zAxis: Vector3 = new Vector3(0, 0, 1)
) {
const rotation = new Matrix4();
const yAxis = new Vector3().crossVectors(zAxis, xAxis).normalize();
rotation.makeBasis(xAxis.normalize(), yAxis, zAxis.normalize());
const transformation = new Matrix4();
transformation.compose(point, new Quaternion().setFromRotationMatrix(rotation), new Vector3(1, 1, 1));
return transformation;
}
}
6 changes: 3 additions & 3 deletions src/services/files_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ class FilesService {
private models: Array<IfcModel> = [];
private elements: ModelElements = {};
private readonly DEFAULT_PARSER_SETTINGS: ParserSettings = {
namespace: "http://www.theproject.org/",
namespace: "http://www.sample.org/",
subsets: {
BOT: true,
FSO: true,
PRODUCTS: false,
PROPERTIES: false,
PRODUCTS: true,
PROPERTIES: true,
},
outputFormat: SerializationFormat.JSONLD,
normalizeToSIUnits: false,
Expand Down
3 changes: 3 additions & 0 deletions src/services/ifc_controller_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { GuidOperations } from "@helpers/guid_operations";
import { ConnectedElements } from "@/types/connected_elements";
import { IfcElement } from "@/types/ifc_element";
import { ConnectorsManager } from "@services/connectors_manager";
import { ElementPlacementService } from "@services/element-placement.service";

class IfcControllerService {

Expand All @@ -27,6 +28,8 @@ class IfcControllerService {
public async getAllUnconnectedConnectors(modelID: number): Promise<IfcElement[]> {
const connectorManager = new ConnectorsManager(this.ifcAPI);
await connectorManager.addUnconnectedConnectors(modelID);
const elementPlacementService = new ElementPlacementService(this.ifcAPI);
await elementPlacementService.getElementsCoordinates(modelID)
return connectorManager.getAllUnconnectedElements();
}

Expand Down

0 comments on commit e6e59ac

Please sign in to comment.