Last active
November 13, 2024 14:13
-
-
Save giobel/08e254a4ee54c6f38425c4b6c93b450a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# IFC files using XBim and Geometry Gym |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Power BI Visual CLI | |
* | |
* Copyright (c) Microsoft Corporation | |
* All rights reserved. | |
* MIT License | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy | |
* of this software and associated documentation files (the ""Software""), to deal | |
* in the Software without restriction, including without limitation the rights | |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the Software is | |
* furnished to do so, subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in | |
* all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
* THE SOFTWARE. | |
*/ | |
"use strict"; | |
import powerbi from "powerbi-visuals-api"; | |
import { FormattingSettingsService } from "powerbi-visuals-utils-formattingmodel"; | |
import "./../style/visual.less"; | |
import * as THREE from 'three'; | |
import * as OBC from 'openbim-components'; | |
import { FragmentsGroup, Fragment } from 'bim-fragment'; | |
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions; | |
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions; | |
import IVisual = powerbi.extensibility.visual.IVisual; | |
import { VisualFormattingSettingsModel } from "./settings"; | |
export class Visual implements IVisual { | |
private target: HTMLElement; | |
private updateCount: number; | |
private textNode: Text; | |
private formattingSettings: VisualFormattingSettingsModel; | |
private formattingSettingsService: FormattingSettingsService; | |
private viewer: OBC.Components; | |
private fragMap: { [expressID: string]: {fragment: Fragment} } = {}; | |
private guidToexpressIdMap: { [expressID: string]: number } = {}; | |
private propertiesProcessor: OBC.IfcPropertiesProcessor; | |
private green : THREE.Color = new THREE.Color(0x5CC45C) | |
private red: THREE.Color = new THREE.Color(0xCC0000) | |
private highlighter: OBC.FragmentHighlighter | |
private tco2Values: {[ifcGuid: string]: {value: number, update: boolean}} = {} | |
private model: FragmentsGroup | |
private async LoadModel(filepath: string, viewer: OBC.Components, fragmentLoader:OBC.FragmentIfcLoader, fragmentManager: OBC.FragmentManager, scene: THREE.Scene, propertiesProcessor: OBC.IfcPropertiesProcessor){ | |
try{ | |
fragmentLoader.settings.wasm = { | |
path: "https://unpkg.com/web-ifc@0.0.43/", | |
absolute: true | |
} | |
fragmentLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true; | |
fragmentLoader.settings.webIfc.OPTIMIZE_PROFILES = true; | |
const file = await fetch(filepath); | |
console.log(file) | |
const data = await file.arrayBuffer(); | |
console.log(data) | |
const buffer = new Uint8Array(data); | |
this.model = await fragmentLoader.load(buffer, 'test'); | |
scene.add(this.model); | |
console.log('model', this.model) | |
propertiesProcessor.process(this.model) | |
const fragmentsGroup = fragmentManager.groups[0] | |
const { properties } = OBC.IfcPropertiesManager.getIFCInfo(fragmentsGroup); | |
for (const [key] of Object.entries(properties)) { | |
try{ | |
//console.log(properties[parseInt(key)]) | |
const {expressID, GlobalId} = properties[parseInt(key)]; | |
if (expressID && GlobalId){ | |
this.guidToexpressIdMap[GlobalId.value] = expressID | |
} | |
} | |
catch(error){ | |
//console.log('error', error) | |
} | |
} | |
//console.log('guidExIdMap', this.guidToexpressIdMap) | |
for (const frag of fragmentsGroup.items){ | |
//console.log(frag) | |
for (let index = 0; index < frag.items.length; index++) { | |
this.fragMap[frag.items[index]] = {fragment: frag} | |
} | |
} | |
//console.log('fragmap', this.fragMap) | |
return this.model | |
} | |
catch(error){ | |
console.log('error', error) | |
} | |
} | |
constructor(options: VisualConstructorOptions) { | |
const host = options.host | |
const target = options.element | |
//#region create scene | |
const container = document.createElement( 'div' ) | |
container.className = 'full-screen' | |
container.style.zIndex = '2000' | |
target.style.cursor = 'default' | |
target.appendChild( container ) | |
this.viewer = new OBC.Components() | |
const sceneComponent = new OBC.SimpleScene(this.viewer) | |
sceneComponent.setup() | |
this.viewer.scene = sceneComponent | |
this.viewer.scene.get().background = new THREE.Color( 0xf3f3f7 ); | |
const rendererComponent = new OBC.PostproductionRenderer(this.viewer, container) | |
this.viewer.renderer = rendererComponent | |
const postproduction = rendererComponent.postproduction | |
const cameraComponent = new OBC.OrthoPerspectiveCamera(this.viewer) | |
this.viewer.camera = cameraComponent | |
cameraComponent.controls.setLookAt( 10, 10, 10, 0, 0, 0 ); | |
const raycasterComponent = new OBC.SimpleRaycaster(this.viewer) | |
this.viewer.raycaster = raycasterComponent | |
this.viewer.init() | |
cameraComponent.updateAspect() | |
postproduction.enabled = true | |
//const grid = new OBC.SimpleGrid(this.viewer, new THREE.Color(0x666666)) | |
//postproduction.customEffects.excludedMeshes.push(grid.get()) | |
const fragmentManager = new OBC.FragmentManager(this.viewer) | |
const ifcLoader = new OBC.FragmentIfcLoader(this.viewer) | |
// this.highlighter = new OBC.FragmentHighlighter(this.viewer) | |
// this.highlighter.setup() | |
// this.highlighter.add('notSelected', [new THREE.MeshStandardMaterial({color: 0x808080})]) | |
this.propertiesProcessor = new OBC.IfcPropertiesProcessor(this.viewer) | |
// this.highlighter.events.select.onClear.add(() => { | |
// propertiesProcessor.cleanPropertiesList() | |
// }) | |
//#endregion | |
const mainToolbar = new OBC.Toolbar(this.viewer) | |
mainToolbar.addChild( | |
this.propertiesProcessor.uiElement.get("main") | |
) | |
this.viewer.ui.addToolbar(mainToolbar) | |
this.LoadModel('http://localhost:5173/CSW-2200-crop.ifc', this.viewer, ifcLoader, fragmentManager, this.viewer.scene.get(), this.propertiesProcessor) | |
} | |
private async addColor(highlighter: OBC.FragmentHighlighter, percentage: number, fragMap: OBC.FragmentIdMap){ | |
await highlighter.highlightByID(percentage.toString(), fragMap, true, true) | |
} | |
public update(options: VisualUpdateOptions) { | |
console.log('update') | |
console.log(this.highlighter) | |
if (this.highlighter){ | |
console.log('dispose highlighter') | |
//this.highlighter.dispose(); | |
this.highlighter.clear(); | |
} | |
console.log('viewer', this.viewer) | |
this.highlighter = new OBC.FragmentHighlighter(this.viewer) | |
this.highlighter.setup() | |
this.highlighter.update() | |
console.log(this.highlighter) | |
try{ | |
this.highlighter.events.select.onHighlight.add((selection) => { | |
const fragmentID = Object.keys(selection)[0] | |
const expressID = Number([...selection[fragmentID]][0]) | |
this.propertiesProcessor.renderProperties(this.model, expressID) | |
}) | |
this.highlighter.update() | |
this.highlighter.add('notSelected', [new THREE.MeshStandardMaterial({color: 0x808080})]) | |
this.highlighter.events.select.onClear.add(() => { | |
this.propertiesProcessor.cleanPropertiesList() | |
}) | |
} | |
catch(error){console.log(error)} | |
//console.log('Visual update', options); | |
//this.highlighter.clear() | |
// const propertiesProcessor = new OBC.IfcPropertiesProcessor(this.viewer) | |
// this.highlighter.events.select.onClear.add(() => { | |
// propertiesProcessor.cleanPropertiesList() | |
// }) | |
let dataViews = options.dataViews; | |
console.log('datavview', dataViews) | |
let categorical = dataViews[0].categorical; | |
let guids = <string[]>categorical.categories[0].values; | |
let tco2 = <number[]>categorical.values[0].values; | |
let volumes = <number[]>categorical.values[1].values; | |
//const tco2Values: {[ifcGuid: string]: {value: number, update: boolean}} = {} | |
for (let index = 0; index < tco2.length; index++) { | |
//console.log(data) | |
const tco2value = tco2[index]* volumes[index] | |
if (!this.tco2Values[guids[index]]){ | |
this.tco2Values[guids[index]] = {value:tco2value, update:true} | |
} | |
} | |
let tco2Max = 0 | |
for (const key in this.tco2Values) { | |
if (this.tco2Values[key].value > tco2Max) { | |
tco2Max = this.tco2Values[key].value; | |
} | |
} | |
for (let index = 0; index < guids.length; index++) { | |
const expressID = this.guidToexpressIdMap[guids[index]]; | |
if (expressID){ | |
const foundItem = Object.entries(this.fragMap).find(([x]) => x === String(expressID)); | |
console.log(foundItem) | |
const percentage = tco2[index]*volumes[index]/(tco2Max) | |
//console.log(percentage) | |
const colorT = new THREE.Color() | |
colorT.lerpColors(this.green, this.red, percentage) | |
const existingMaterial = this.highlighter.highlightMats[percentage.toString()] | |
if (!existingMaterial){ | |
this.highlighter.add(percentage.toString(), [new THREE.MeshStandardMaterial({color: colorT})]) | |
} | |
const {fragment} = foundItem[1] | |
const fragmentmap: OBC.FragmentIdMap = {} | |
fragmentmap[fragment.id] = new Set<string>(); | |
fragmentmap[fragment.id].add(expressID.toString()) | |
//console.log('guid', item[0]) | |
//console.log('fid map', mybeam) | |
this.addColor(this.highlighter, percentage, fragmentmap) | |
//this.highlighter.highlightByID(percentage.toString(), fragmentmap, true, true) | |
} | |
} | |
/* | |
for (const guid of Object.entries(this.tco2Values)){ | |
console.log('guid', guid[0]) | |
if (guids.includes(guid[0])){ | |
//update | |
this.tco2Values[guid[0]].update = true | |
//console.log('update') | |
} | |
else{ | |
//do not update | |
//console.log('not update') | |
this.tco2Values[guid[0]].update = false | |
} | |
} | |
console.log('guid', guids) | |
console.log('guidmap', this.guidToexpressIdMap) | |
console.log(this.tco2Values) | |
//this.highlighter.clear(); | |
for (const item of Object.entries(this.tco2Values)){ | |
const expressID = this.guidToexpressIdMap[item[0]]; | |
if (expressID){ | |
const foundItem = Object.entries(this.fragMap).find(([x]) => x === String(expressID)); | |
if (item[1].update){ | |
console.log(foundItem) | |
const percentage = item[1].value/(tco2Max) | |
//console.log(percentage) | |
const colorT = new THREE.Color() | |
colorT.lerpColors(this.green, this.red, percentage) | |
const existingMaterial = this.highlighter.highlightMats[percentage.toString()] | |
//console.log('ex material', existingMaterial) | |
if (!existingMaterial){ | |
this.highlighter.add(percentage.toString(), [new THREE.MeshStandardMaterial({color: colorT})]) | |
} | |
const {fragment} = foundItem[1] | |
const mybeam: OBC.FragmentIdMap = {} | |
mybeam[fragment.id] = new Set<string>(); | |
mybeam[fragment.id].add(expressID.toString()) | |
//console.log('guid', item[0]) | |
//console.log('fid map', mybeam) | |
this.highlighter.highlightByID(percentage.toString(), mybeam, true, true) | |
} | |
else{ | |
//console.log('grey color') | |
const {fragment} = foundItem[1] | |
const mybeam: OBC.FragmentIdMap = {} | |
mybeam[fragment.id] = new Set<string>(); | |
mybeam[fragment.id].add(expressID.toString()) | |
//this.highlighter.highlightByID('notSelected', mybeam, true, true) | |
//this.highlighter.fillEnabled = false | |
} | |
} | |
} | |
*/ | |
//this.highlighter.update() | |
//this.viewer.scene.get().updateMatrix() | |
console.log('done') | |
console.log(this.highlighter) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
XbimPoint3D minPt = new XbimPoint3D(-45700, -27800, -10000); | |
XbimPoint3D maxPt = new XbimPoint3D(-32732, 0, 1000); | |
XbimRect3D selBox = new XbimRect3D(minPt,maxPt); //bounding box you need | |
foreach (var instance in instances) | |
{ | |
var transfor = instance.Transformation; //Transformation matrix (location point inside) | |
XbimShapeGeometry geometry = context.ShapeGeometry(instance); //Instance's geometry | |
XbimRect3D box = geometry.BoundingBox; //bounding box you need | |
var wcsbox = box.Transform(transfor); | |
if (selBox.Intersects(wcsbox)) | |
{ | |
Console.WriteLine($"#{instance.IfcProductLabel} Intersects!"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://stackoverflow.com/questions/56596815/how-to-retrieve-geometry-from-ifc-file-using-xbim-or-is-there-anyother-alterna | |
using (var model = IfcStore.Open("ifc_file.ifc")) | |
{ | |
Xbim3DModelContext context = new Xbim3DModelContext(model); | |
context.CreateContext(); | |
List<XbimShapeGeometry> geometrys = context.ShapeGeometries().ToList(); | |
List<XbimShapeInstance> instances = context.ShapeInstances().ToList(); | |
//Check all the instances | |
foreach (var instance in instances) | |
{ | |
var transfor = instance.Transformation; //Transformation matrix (location point inside) | |
XbimShapeGeometry geometry = context.ShapeGeometry(instance); //Instance's geometry | |
XbimRect3D box = geometry.BoundingBox; //bounding box you need | |
var wcsbox = box.Transform(transfor); | |
byte[] datas = ((IXbimShapeGeometryData)geometry).ShapeData; | |
Console.WriteLine($"item #{instance.IfcProductLabel} shape geo label {instance.ShapeGeometryLabel} " + | |
$" loc: min {wcsbox.Min} max {wcsbox.Max}"); | |
XbimRect3D box = geometry.BoundingBox; //bounding box you need | |
byte[] data = ((IXbimShapeGeometryData)geometry).ShapeData; | |
//If you want to get all the faces and trinagulation use this | |
using (var stream = new MemoryStream(data)) | |
{ | |
using (var reader = new BinaryReader(stream)) | |
{ | |
var mesh = reader.ReadShapeTriangulation(); | |
List<XbimFaceTriangulation> faces = mesh.Faces as List<XbimFaceTriangulation>; | |
List<XbimPoint3D> vertices = mesh.Vertices as List<XbimPoint3D>; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://github.com/xBimTeam/XbimEssentials/issues/340#issuecomment-649715537 | |
using Xbim.Common; | |
using Xbim.Ifc; | |
using Xbim.Ifc4.Interfaces; | |
// snip | |
var fileName="your.ifc"; | |
using (var model = IfcStore.Open(fileName)) | |
{ | |
IEnumerable<int> matchingElements = from i in model.Instances.OfType<IIfcRelDefinesByProperties>() | |
// Find all properties in Pset called 'Dimensions' with 'Area' > 20.5 | |
where i.RelatingPropertyDefinition is IIfcPropertySet | |
let pset = i.RelatingPropertyDefinition as IIfcPropertySet | |
where pset.Name == "Dimensions" | |
let property = pset.HasProperties.OfType<IIfcPropertySingleValue>().FirstOrDefault(v => v.Name == "Area") | |
where property?.NominalValue is IExpressRealType | |
where ((IExpressRealType)property.NominalValue).Value > 20.5d | |
// Now get the elements | |
from element in i.RelatedObjects | |
select element.EntityLabel; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# IFC creation using Geometry Gym | |
using GeometryGym.Ifc; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Reflection; | |
using System.Windows; | |
namespace CreatePiles | |
{ | |
/// <summary> | |
/// Interaction logic for MainWindow.xaml | |
/// </summary> | |
public partial class MainWindow : Window | |
{ | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
} | |
private void Button_Click(object sender, RoutedEventArgs e) | |
{ | |
DatabaseIfc db = new DatabaseIfc(ModelView.Ifc2x3Coordination); | |
IfcSite site = new IfcSite(db, "Site01"); | |
IfcLocalPlacement locPlace = site.ObjectPlacement as IfcLocalPlacement; | |
IfcAxis2Placement3D wcsPlace = locPlace.RelativePlacement as IfcAxis2Placement3D; | |
wcsPlace.Location = new IfcCartesianPoint(db, 1000, 2000, 300); | |
wcsPlace.Axis = new IfcDirection(db, 0, 0, 1); | |
wcsPlace.RefDirection = new IfcDirection(db, 1, 0, 0); | |
IfcProject project = new IfcProject(site, "IfcProject", IfcUnitAssignment.Length.Metre) { }; | |
IfcBuilding building = new IfcBuilding(site, "Station") { }; | |
IfcBuildingStorey storey = new IfcBuildingStorey(building, "Base Level", 0); | |
List<IfcProperty> properties = new List<IfcProperty>(); | |
//PROPERTIES WILL BE THE SAME FOR ALL PILES | |
//IfcPropertySingleValue psv = new IfcPropertySingleValue(db, "Is Constructed", new IfcBoolean(false)); | |
//properties.Add(psv); | |
//IfcPropertySingleValue psv2 = new IfcPropertySingleValue(db, "Material", "Concrete"); | |
//properties.Add(psv2); | |
//IfcPropertySingleValue psv1 = new IfcPropertySingleValue(db, "Pile Name", "Placeholder"); | |
//properties.Add(psv1); | |
//this way the property is the same for all piles (can't edit single pile value) | |
//IfcPropertySingleValue constructProperty = new IfcPropertySingleValue(db, "Is Constructed", new IfcBoolean(false)); | |
List<Pile> piles = new List<Pile>(); | |
using (var reader = new StreamReader(this.inputCsvFile.Text)) | |
{ | |
string headerLine = reader.ReadLine(); | |
string line; | |
while ((line = reader.ReadLine()) != null) | |
{ | |
if ( line != "") | |
{ | |
var values = line.Split(','); | |
piles.Add(new Pile(values[0], int.Parse(values[1]), double.Parse(values[2]), double.Parse(values[3]), double.Parse(values[4]), double.Parse(values[5]))); | |
} | |
} | |
} | |
IfcMaterial mat = new IfcMaterial(db, "Steel"); | |
IfcProfileDef pdef = new IfcProfileDef(db, "150UC37.2"); | |
IfcMaterialProfile matProf = new IfcMaterialProfile("150UC", mat, pdef); | |
//IfcColumnStandardCase col = new IfcColumnStandardCase(db, new IfcMaterialProfileSetUsage()) | |
List<IfcPile> ifcpiles = new List<IfcPile>(); | |
foreach (Pile item in piles) | |
{ | |
IfcExtrudedAreaSolid extrudedAreaSolid = new IfcExtrudedAreaSolid(new IfcCircleProfileDef(db, $"D{item.Diameter}", item.Diameter*0.0005), item.Length); | |
IfcProductDefinitionShape productDefinitionShape = new IfcProductDefinitionShape(new IfcShapeRepresentation(extrudedAreaSolid)); | |
IfcObjectPlacement placement = new IfcLocalPlacement( | |
new IfcAxis2Placement3D( | |
new IfcCartesianPoint(db, item.Easting, item.Northings, item.CutOffLevel) | |
) | |
); | |
placement.PlacementRelTo = site.ObjectPlacement; | |
//building container | |
//IfcPile pile = new IfcPile(building, placement, productDefinitionShape); | |
//or storey container | |
IfcPile pile = new IfcPile(storey, placement, productDefinitionShape); | |
pile.Name = item.Name; | |
pile.Description = $"A bored {item.Diameter} dia pile"; | |
pile.ConstructionType = IfcPileConstructionEnum.BORED; | |
ifcpiles.Add(pile); | |
IfcPropertySet pilePSet = new IfcPropertySet(pile, "SEPA"); | |
pilePSet.AddProperty(new IfcPropertySingleValue(db, "Pile Name", item.Name)); | |
pilePSet.AddProperty(new IfcPropertySingleValue(db, "Diameter", item.Diameter)); | |
//pilePSet.AddProperty(constructProperty); //this way the property is the same for all piles (can't edit single pile value) | |
pilePSet.AddProperty(new IfcPropertySingleValue(db, "Is Constructed", new IfcBoolean(false))); | |
//new IfcRelDefinesByProperties(pile, pilePSet); | |
//IfcPropertySet pilePSet = pile.FindPropertySet("SEPA") as IfcPropertySet; | |
// IfcPropertySingleValue pileNameProp = pilePSet.FindProperty("Pile Name") as IfcPropertySingleValue; | |
// pileNameProp.NominalValue.Value = item.Name; | |
//IfcPropertySingleValue psv1 = new IfcPropertySingleValue(db, "Name", pile.Name); | |
//properties.Add(psv1); | |
} | |
//foreach (IfcPile pile in ifcpiles) | |
//{ | |
// IfcPropertySet pilePSet = pile.FindPropertySet("SEPA") as IfcPropertySet; | |
// pilePSet.AddProperty(constructProperty); | |
//} | |
db.WriteFile(this.outputFolder.Text); | |
System.Diagnostics.Process.Start(this.outputFolder.Text); | |
} | |
} | |
internal class Pile | |
{ | |
public string Name { get; set; } | |
public int Diameter { get; set; } | |
public double Easting { get; set; } | |
public double Northings { get; set; } | |
public double CutOffLevel { get; set; } | |
public double Length { get; set; } | |
public Pile(string Name, int Diameter, double Easting, double Northern, double CutOffLevel, double Length) | |
{ | |
this.Name = Name; | |
this.Diameter = Diameter; | |
this.Easting = Easting; | |
this.Northings = Northern; | |
this.CutOffLevel = CutOffLevel; | |
this.Length = Length; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import ifcopenshell | |
import trimesh | |
import numpy as np | |
def get_ifc_files(directory): | |
# List all files in the directory | |
files = os.listdir(directory) | |
# Filter only .ifc files | |
ifc_files = [file for file in files if file.lower().endswith('.ifc')] | |
return ifc_files | |
def extract_local_placement_and_point(ifc_file): | |
# Look for entities of type IfcLocalPlacement | |
local_placements = ifc_file.by_type("IfcLocalPlacement") | |
if not local_placements: | |
print("No IfcLocalPlacement found in the file.") | |
return None | |
# Iterate through each IfcLocalPlacement entity | |
for local_placement in local_placements: | |
# Get the relative placement (it should contain an IfcAxis2Placement3D or IfcCartesianPoint) | |
relative_placement = local_placement.RelativePlacement | |
if relative_placement and hasattr(relative_placement, "Location"): | |
# Extract the location (If it's an IfcCartesianPoint, you get the coordinates) | |
location = relative_placement.Location | |
if location and location.is_a("IfcCartesianPoint"): | |
# Extract the Cartesian coordinates | |
x = location.Coordinates[0] | |
y = location.Coordinates[1] | |
z = location.Coordinates[2] if len(location.Coordinates) > 2 else 0.0 # Default Z to 0 if missing | |
result = f"LocalPlacement Location: X={x}, Y={y}, Z={z}" | |
#print(f"LocalPlacement Location: X={x}, Y={y}, Z={z}") | |
return result | |
print("No IfcCartesianPoint found in any IfcLocalPlacement.") | |
return None | |
allFiles = get_ifc_files(folder) | |
for fileName in allFiles: | |
ifc_file = ifcopenshell.open(folder+'\\'+fileName) | |
products = ifc_file.by_type("IfcProduct") | |
for p in products: | |
type = ifcopenshell.util.element.get_type(p) | |
print (type) | |
psets = ifcopenshell.util.element.get_psets(p) | |
pset = ifcopenshell.util.element.get_pset(p, 'BaseQuantities')['NetVolume'] | |
print (pset) | |
break | |
site = None | |
for s in ifc_file.by_type("IfcSite"): | |
site = s | |
break # Assuming there's only one site in the file, you can remove this if multiple sites exist | |
if site is None: | |
print("No IfcSite found in the file.") | |
geographic_location = site.get_info(True)['ObjectPlacement'] | |
local_placements = extract_local_placement_and_point(ifc_file) | |
print (fileName + " " + local_placements) | |
break | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import * as OBC from "openbim-components" | |
import * as THREE from "three" | |
import { Fragment } from "bim-fragment"; | |
import { color } from 'three/examples/jsm/nodes/Nodes.js'; | |
const TCdata =[ | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 22, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail0", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.303" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 23, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail7", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 24, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail6", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 26, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail5", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 27, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail4", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 28, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtaiWx", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 29, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtaiWw", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 14, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIO2", | |
"mixType": "VR535/65", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.4269, | |
"volume": "1.375" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 6, | |
"ifcGUID": "0yzQgqfmjFMxAsJeeoKgk8", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.925" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 2, | |
"ifcGUID": "23Rn8oK6XBKPC0kMTttlFx", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.447" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 15, | |
"ifcGUID": "3sVk1mOwbExhUkvilYAT62", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.444" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 17, | |
"ifcGUID": "0zIVzQ4GT9fPRoeUGfzqp9", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.444" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 18, | |
"ifcGUID": "0hzINTH11819vAcsaJSN$l", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.444" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 20, | |
"ifcGUID": "2ouI1mE9P6Hhdor6$1lFOE", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.101" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 41, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQJu", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 16, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$VW", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 19, | |
"ifcGUID": "3SAVs4fkT0Bh2MxZMwdX$q", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 33, | |
"ifcGUID": "1ipwC82Hr6k8quZdAck27W", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 0, | |
"ifcGUID": "25lA26vsP69AU1XNSA6bZE", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.661" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 25, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Vc", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 30, | |
"ifcGUID": "1WXgstI7f79x6VgYVpMKIS", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 34, | |
"ifcGUID": "2_1uf7JOL7kgdbGPYR48fO", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 42, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQJw", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 7, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIO6", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.658" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 43, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQJy", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 35, | |
"ifcGUID": "2GbIojRS95lPgC6muSNFgp", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 3, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIO4", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.499" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 21, | |
"ifcGUID": "1Y5QF84jv6zRGMNAWgjJGp", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 5, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Va", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 4, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQJ_", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 31, | |
"ifcGUID": "1cfv5D7f982g2IBjUwZ2xm", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 1, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Vg", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 36, | |
"ifcGUID": "0nuO8mIVb0NAE6UWMLiNBV", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 8, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIOu", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.496" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 44, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQI0", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 9, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIOw", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.496" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 10, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Ve", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 37, | |
"ifcGUID": "3qAzL9s393lPXc6mKQLZR2", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 40, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQI2", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 39, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Vk", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 38, | |
"ifcGUID": "1aZNOaxOL7R9Gvdm6ceIqB", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 12, | |
"ifcGUID": "0fu1_CJJbCheMhMp09uGsj", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 32, | |
"ifcGUID": "1rwepkfnH3ngdBK4L$ZWGI", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 11, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIO_", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.497" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 13, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIOy", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.377" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 45, | |
"ifcGUID": "1veR3NRpjCYQOtDyFkigty", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.067" | |
} | |
] | |
const green = new THREE.Color(0x5CC45C) | |
const red = new THREE.Color(0xCC0000) | |
console.log(green, red) | |
export default () => { | |
const [modelCount, setModelCount] = React.useState(0) | |
function getRandomColor() { | |
return new THREE.Color(Math.random(), Math.random(), Math.random()); | |
} | |
const tco2Values: {[ifcGuid: string]: number} = {} | |
for (const data of TCdata){ | |
//console.log(data) | |
const tco2 = data.tCO2_m3* Number.parseFloat(data.volume) | |
tco2Values[data.ifcGUID] = tco2 | |
} | |
//const tco2Min = Math.min(...Object.values(tco2Values)) | |
const tco2Max = Math.max(...Object.values(tco2Values)) | |
React.useEffect(() => { | |
const viewer = new OBC.Components() | |
const sceneComponent = new OBC.SimpleScene(viewer) | |
sceneComponent.setup() | |
viewer.scene = sceneComponent | |
const viewerContainer = document.getElementById("viewerContainer") as HTMLDivElement | |
const rendererComponent = new OBC.PostproductionRenderer(viewer, viewerContainer) | |
viewer.renderer = rendererComponent | |
const postproduction = rendererComponent.postproduction | |
const cameraComponent = new OBC.OrthoPerspectiveCamera(viewer) | |
viewer.camera = cameraComponent | |
const raycasterComponent = new OBC.SimpleRaycaster(viewer) | |
viewer.raycaster = raycasterComponent | |
viewer.init() | |
cameraComponent.updateAspect() | |
postproduction.enabled = true | |
const grid = new OBC.SimpleGrid(viewer, new THREE.Color(0x666666)) | |
postproduction.customEffects.excludedMeshes.push(grid.get()) | |
const fragmentManager = new OBC.FragmentManager(viewer) | |
const ifcLoader = new OBC.FragmentIfcLoader(viewer) | |
const highlighter = new OBC.FragmentHighlighter(viewer) | |
highlighter.setup() | |
const propertiesProcessor = new OBC.IfcPropertiesProcessor(viewer) | |
highlighter.events.select.onClear.add(() => { | |
propertiesProcessor.cleanPropertiesList() | |
}) | |
const fragmentClassifier = new OBC.FragmentClassifier(viewer) | |
const guidToexpressIdMap: { [expressID: string]: number } = {}; | |
async function loadIfcAsFragments(path: string, ifcLoader : OBC.FragmentIfcLoader, scene: THREE.Scene) { | |
const file = await fetch(path); | |
//console.log(file) | |
const data = await file.arrayBuffer(); | |
//console.log(data) | |
const buffer = new Uint8Array(data); | |
const model = await ifcLoader.load(buffer, 'test'); | |
scene.add(model); | |
console.log('model', model) | |
setModelCount(fragmentManager.groups.length) | |
propertiesProcessor.process(model) | |
highlighter.events.select.onHighlight.add((selection) => { | |
const fragmentID = Object.keys(selection)[0] | |
const expressID = Number([...selection[fragmentID]][0]) | |
propertiesProcessor.renderProperties(model, expressID) | |
}) | |
highlighter.update() | |
//fragmentClassifier.byEntity(model) | |
//console.log('fra group', fragmentsGroup) | |
//const { properties } = OBC.IfcPropertiesManager.getIFCInfo(fragmentsGroup); | |
//console.log(properties) | |
//fragmentClassifier.byModel(model.id.toString(), fragmentsGroup) | |
//fragmentClassifier.byPredefinedType(fragmentsGroup) | |
//const entities = fragmentClassifier.get().entities | |
//console.log('entities', entities) | |
//console.log('slab', entities['IFCSLAB']) | |
// for (const entity in entities){ | |
// console.log('entity', entity) | |
// highlighter.add(entity, [new THREE.MeshStandardMaterial({color: getRandomColor()})]) | |
// console.log('ee', entities[entity]) | |
// highlighter.highlightByID(entity, entities[entity], true) | |
// } | |
//MAP IFC GUID TO EXPRESSID | |
const fragmentsGroup = fragmentManager.groups[0] | |
const { properties } = OBC.IfcPropertiesManager.getIFCInfo(fragmentsGroup); | |
for (const [key] of Object.entries(properties)) { | |
try{ | |
//console.log(properties[parseInt(key)]) | |
const {expressID, GlobalId} = properties[parseInt(key)]; | |
if (expressID && GlobalId){ | |
guidToexpressIdMap[GlobalId.value] = expressID | |
} | |
} | |
catch{} | |
} | |
console.log('pmasp', guidToexpressIdMap) | |
const fragment = fragmentManager.list; | |
//console.log('fragment', fragment) | |
const f = fragmentsGroup.items[0] | |
//console.log('f', f) | |
const mybeam: OBC.FragmentIdMap = {} | |
mybeam[f.id] = new Set<string>(); | |
mybeam[f.id].add("3010"); | |
mybeam[f.id].add("2946"); | |
mybeam[f.id].add("138"); | |
mybeam[f.id].add("1603"); | |
console.log(mybeam) | |
// highlighter.add('slab-material', [new THREE.MeshStandardMaterial({color: red})]) | |
// highlighter.highlightByID('slab-material', mybeam, true) | |
const fragMap: { [expressID: string]: {fragment: Fragment} } = {}; | |
for (const frag of fragmentsGroup.items){ | |
//console.log(frag) | |
for (let index = 0; index < frag.items.length; index++) { | |
fragMap[frag.items[index]] = {fragment: frag} | |
} | |
} | |
console.log('tc values', tco2Values) | |
console.log(tco2Max) | |
for (const item of Object.entries(tco2Values)){ | |
console.log('item', item) | |
const expressID = guidToexpressIdMap[item[0]]; | |
if (expressID){ | |
const foundItem = Object.entries(fragMap).find(([x]) => x === String(expressID)); | |
console.log(foundItem) | |
if (foundItem){ | |
//item co2 value/max co2 value | |
const percentage = item[1]/tco2Max | |
console.log(percentage) | |
const colorT = new THREE.Color() | |
colorT.lerpColors(green, red, percentage) | |
console.log(colorT) | |
highlighter.add(percentage.toString(), [new THREE.MeshStandardMaterial({color: colorT})]) | |
const {fragment} = foundItem[1] | |
const mybeam: OBC.FragmentIdMap = {} | |
mybeam[fragment.id] = new Set<string>(); | |
mybeam[fragment.id].add(expressID.toString()) | |
highlighter.highlightByID(percentage.toString(), mybeam, true) | |
console.log(fragment) | |
} | |
} | |
} | |
return model | |
} | |
//const path = 'http://localhost:5173/small.ifc' | |
//const path = 'http://localhost:5173/SBS-2322.ifc' | |
//const path = 'http://localhost:5173/DETACHED.ifc' | |
const path = 'http://localhost:5173/CSW-2200-crop.ifc' | |
//const path = 'http://localhost:5173/SEP-084-C-SEPA-MOD-13-RWE-CSW-2200_IFC.ifc' | |
loadIfcAsFragments(path, ifcLoader, viewer.scene.get()) | |
const mainToolbar = new OBC.Toolbar(viewer) | |
mainToolbar.addChild( | |
ifcLoader.uiElement.get("main"), | |
propertiesProcessor.uiElement.get("main") | |
) | |
viewer.ui.addToolbar(mainToolbar) | |
}, []) | |
const viewerContainerStyle: React.CSSProperties = { | |
width: "100%", | |
height: "100%", | |
position: "relative", | |
gridArea: "viewer" | |
} | |
const titleStyle: React.CSSProperties = { | |
position: "absolute", | |
top: "15px", | |
left: "15px" | |
} | |
return ( | |
<> | |
<div id="viewerContainer" style={viewerContainerStyle}> | |
<h3 style={titleStyle}>Models loaded: {modelCount}</h3> | |
</div> | |
</> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import * as OBC from "openbim-components" | |
import * as THREE from "three" | |
import { Fragment } from "bim-fragment"; | |
import { color } from 'three/examples/jsm/nodes/Nodes.js'; | |
const TCdata =[ | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 22, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail0", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.303" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 23, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail7", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 24, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail6", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 26, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail5", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 27, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtail4", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 28, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtaiWx", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 29, | |
"ifcGUID": "069xHa4Sv9FgrxXmVtaiWw", | |
"mixType": "VR450/50", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.3594, | |
"volume": "1.209" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 14, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIO2", | |
"mixType": "VR535/65", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.4269, | |
"volume": "1.375" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 6, | |
"ifcGUID": "0yzQgqfmjFMxAsJeeoKgk8", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.925" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 2, | |
"ifcGUID": "23Rn8oK6XBKPC0kMTttlFx", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.447" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 15, | |
"ifcGUID": "3sVk1mOwbExhUkvilYAT62", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.444" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 17, | |
"ifcGUID": "0zIVzQ4GT9fPRoeUGfzqp9", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.444" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 18, | |
"ifcGUID": "0hzINTH11819vAcsaJSN$l", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.444" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 20, | |
"ifcGUID": "2ouI1mE9P6Hhdor6$1lFOE", | |
"mixType": "VR400/40", | |
"supplier": "Holcim", | |
"tCO2_m3": 0.1886, | |
"volume": "1.101" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 41, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQJu", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 16, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$VW", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 19, | |
"ifcGUID": "3SAVs4fkT0Bh2MxZMwdX$q", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 33, | |
"ifcGUID": "1ipwC82Hr6k8quZdAck27W", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 0, | |
"ifcGUID": "25lA26vsP69AU1XNSA6bZE", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.661" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 25, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Vc", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 30, | |
"ifcGUID": "1WXgstI7f79x6VgYVpMKIS", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 34, | |
"ifcGUID": "2_1uf7JOL7kgdbGPYR48fO", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 42, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQJw", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 7, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIO6", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.658" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 43, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQJy", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 35, | |
"ifcGUID": "2GbIojRS95lPgC6muSNFgp", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 3, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIO4", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.499" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 21, | |
"ifcGUID": "1Y5QF84jv6zRGMNAWgjJGp", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 5, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Va", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 4, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQJ_", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 31, | |
"ifcGUID": "1cfv5D7f982g2IBjUwZ2xm", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 1, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Vg", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 36, | |
"ifcGUID": "0nuO8mIVb0NAE6UWMLiNBV", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 8, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIOu", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.496" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 44, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQI0", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 9, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIOw", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.496" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 10, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Ve", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 37, | |
"ifcGUID": "3qAzL9s393lPXc6mKQLZR2", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 40, | |
"ifcGUID": "32iTgiIfbBMg2gdvFyEQI2", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.016" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 39, | |
"ifcGUID": "0I6OWAUgTE0RT3HTt6e$Vk", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 38, | |
"ifcGUID": "1aZNOaxOL7R9Gvdm6ceIqB", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.005" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 12, | |
"ifcGUID": "0fu1_CJJbCheMhMp09uGsj", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 32, | |
"ifcGUID": "1rwepkfnH3ngdBK4L$ZWGI", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 11, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIO_", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.497" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 13, | |
"ifcGUID": "0V8JK1XRr2yBilET5mpIOy", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.377" | |
}, | |
{ | |
"modelId": "C731KCVe5oA", | |
"trimbleid": 45, | |
"ifcGUID": "1veR3NRpjCYQOtDyFkigty", | |
"mixType": "VR400/40", | |
"supplier": "Boral", | |
"tCO2_m3": 0.2906, | |
"volume": "0.067" | |
} | |
] | |
const green = new THREE.Color(0x5CC45C) | |
const red = new THREE.Color(0xCC0000) | |
console.log(green, red) | |
export default () => { | |
const [modelCount, setModelCount] = React.useState(0) | |
function getRandomColor() { | |
return new THREE.Color(Math.random(), Math.random(), Math.random()); | |
} | |
const tco2Values: {[ifcGuid: string]: number} = {} | |
for (const data of TCdata){ | |
//console.log(data) | |
const tco2 = data.tCO2_m3* Number.parseFloat(data.volume) | |
tco2Values[data.ifcGUID] = tco2 | |
} | |
//const tco2Min = Math.min(...Object.values(tco2Values)) | |
const tco2Max = Math.max(...Object.values(tco2Values)) | |
React.useEffect(() => { | |
const viewer = new OBC.Components() | |
const sceneComponent = new OBC.SimpleScene(viewer) | |
sceneComponent.setup() | |
viewer.scene = sceneComponent | |
const viewerContainer = document.getElementById("viewerContainer") as HTMLDivElement | |
const rendererComponent = new OBC.PostproductionRenderer(viewer, viewerContainer) | |
viewer.renderer = rendererComponent | |
const postproduction = rendererComponent.postproduction | |
const cameraComponent = new OBC.OrthoPerspectiveCamera(viewer) | |
viewer.camera = cameraComponent | |
const raycasterComponent = new OBC.SimpleRaycaster(viewer) | |
viewer.raycaster = raycasterComponent | |
viewer.init() | |
cameraComponent.updateAspect() | |
postproduction.enabled = true | |
const grid = new OBC.SimpleGrid(viewer, new THREE.Color(0x666666)) | |
postproduction.customEffects.excludedMeshes.push(grid.get()) | |
const fragmentManager = new OBC.FragmentManager(viewer) | |
const ifcLoader = new OBC.FragmentIfcLoader(viewer) | |
const highlighter = new OBC.FragmentHighlighter(viewer) | |
highlighter.setup() | |
const propertiesProcessor = new OBC.IfcPropertiesProcessor(viewer) | |
highlighter.events.select.onClear.add(() => { | |
propertiesProcessor.cleanPropertiesList() | |
}) | |
//const fragmentClassifier = new OBC.FragmentClassifier(viewer) | |
const guidToexpressIdMap: { [expressID: string]: number } = {}; | |
async function loadIfcAsFragments(path: string, ifcLoader : OBC.FragmentIfcLoader, scene: THREE.Scene) { | |
const file = await fetch(path); | |
//console.log(file) | |
const data = await file.arrayBuffer(); | |
//console.log(data) | |
const buffer = new Uint8Array(data); | |
const model = await ifcLoader.load(buffer, 'test'); | |
scene.add(model); | |
console.log('model', model) | |
setModelCount(fragmentManager.groups.length) | |
propertiesProcessor.process(model) | |
highlighter.events.select.onHighlight.add((selection) => { | |
const fragmentID = Object.keys(selection)[0] | |
const expressID = Number([...selection[fragmentID]][0]) | |
propertiesProcessor.renderProperties(model, expressID) | |
}) | |
highlighter.update() | |
//fragmentClassifier.byEntity(model) | |
//console.log('fra group', fragmentsGroup) | |
//const { properties } = OBC.IfcPropertiesManager.getIFCInfo(fragmentsGroup); | |
//console.log(properties) | |
//fragmentClassifier.byModel(model.id.toString(), fragmentsGroup) | |
//fragmentClassifier.byPredefinedType(fragmentsGroup) | |
//const entities = fragmentClassifier.get().entities | |
//console.log('entities', entities) | |
//console.log('slab', entities['IFCSLAB']) | |
// for (const entity in entities){ | |
// console.log('entity', entity) | |
// highlighter.add(entity, [new THREE.MeshStandardMaterial({color: getRandomColor()})]) | |
// console.log('ee', entities[entity]) | |
// highlighter.highlightByID(entity, entities[entity], true) | |
// } | |
//MAP IFC GUID TO EXPRESSID | |
const fragmentsGroup = fragmentManager.groups[0] | |
const { properties } = OBC.IfcPropertiesManager.getIFCInfo(fragmentsGroup); | |
for (const [key] of Object.entries(properties)) { | |
try{ | |
//console.log(properties[parseInt(key)]) | |
const {expressID, GlobalId} = properties[parseInt(key)]; | |
if (expressID && GlobalId){ | |
guidToexpressIdMap[GlobalId.value] = expressID | |
} | |
} | |
catch{} | |
} | |
console.log('pmasp', guidToexpressIdMap) | |
const fragment = fragmentManager.list; | |
//console.log('fragment', fragment) | |
const f = fragmentsGroup.items[0] | |
//console.log('f', f) | |
const mybeam: OBC.FragmentIdMap = {} | |
mybeam[f.id] = new Set<string>(); | |
mybeam[f.id].add("3010"); | |
mybeam[f.id].add("2946"); | |
mybeam[f.id].add("138"); | |
mybeam[f.id].add("1603"); | |
console.log(mybeam) | |
// highlighter.add('slab-material', [new THREE.MeshStandardMaterial({color: red})]) | |
// highlighter.highlightByID('slab-material', mybeam, true) | |
const fragMap: { [expressID: string]: {fragment: Fragment} } = {}; | |
for (const frag of fragmentsGroup.items){ | |
//console.log(frag) | |
for (let index = 0; index < frag.items.length; index++) { | |
fragMap[frag.items[index]] = {fragment: frag} | |
} | |
} | |
console.log('tc values', tco2Values) | |
console.log(tco2Max) | |
for (const item of Object.entries(tco2Values)){ | |
console.log('item', item) | |
const expressID = guidToexpressIdMap[item[0]]; | |
if (expressID){ | |
const foundItem = Object.entries(fragMap).find(([x]) => x === String(expressID)); | |
console.log(foundItem) | |
if (foundItem){ | |
//item co2 value/max co2 value | |
const percentage = item[1]/tco2Max | |
console.log(percentage) | |
const colorT = new THREE.Color() | |
colorT.lerpColors(green, red, percentage) | |
console.log(colorT) | |
highlighter.add(percentage.toString(), [new THREE.MeshStandardMaterial({color: colorT})]) | |
const {fragment} = foundItem[1] | |
const mybeam: OBC.FragmentIdMap = {} | |
mybeam[fragment.id] = new Set<string>(); | |
mybeam[fragment.id].add(expressID.toString()) | |
highlighter.highlightByID(percentage.toString(), mybeam, true) | |
console.log(fragment) | |
} | |
} | |
} | |
return model | |
} | |
//const path = 'http://localhost:5173/small.ifc' | |
//const path = 'http://localhost:5173/SBS-2322.ifc' | |
//const path = 'http://localhost:5173/DETACHED.ifc' | |
const path = 'http://localhost:5173/CSW-2200-crop.ifc' | |
//const path = 'http://localhost:5173/SEP-084-C-SEPA-MOD-13-RWE-CSW-2200_IFC.ifc' | |
loadIfcAsFragments(path, ifcLoader, viewer.scene.get()) | |
const mainToolbar = new OBC.Toolbar(viewer) | |
mainToolbar.addChild( | |
ifcLoader.uiElement.get("main"), | |
propertiesProcessor.uiElement.get("main") | |
) | |
viewer.ui.addToolbar(mainToolbar) | |
}, []) | |
const viewerContainerStyle: React.CSSProperties = { | |
width: "100%", | |
height: "100%", | |
position: "relative", | |
gridArea: "viewer" | |
} | |
const titleStyle: React.CSSProperties = { | |
position: "absolute", | |
top: "15px", | |
left: "15px" | |
} | |
return ( | |
<> | |
<div id="viewerContainer" style={viewerContainerStyle}> | |
<h3 style={titleStyle}>Models loaded: {modelCount}</h3> | |
</div> | |
</> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import * as OBC from "openbim-components" | |
import * as THREE from "three" | |
import { Fragment } from "bim-fragment"; | |
const TCdata = [ | |
{ | |
"modelId": "O96YRmBUFIk", | |
"id": 92, | |
"ifcGUID": "20Kz1qluL2Wg558svTerh7", | |
"materialName": "Holcim", | |
"kgCO2eq": 5047, | |
"volume": "5.600" | |
}, | |
{ | |
"modelId": "O96YRmBUFIk", | |
"id": 95, | |
"ifcGUID": "20Kz1qluL2Wg558svTereQ", | |
"materialName": "Holcim", | |
"kgCO2eq": 5047, | |
"volume": "5.600" | |
}, | |
{ | |
"modelId": "O96YRmBUFIk", | |
"id": 96, | |
"ifcGUID": "20Kz1qluL2Wg558svTerf7", | |
"materialName": "Holcim", | |
"kgCO2eq": 5047, | |
"volume": "5.600" | |
}, | |
{ | |
"modelId": "O96YRmBUFIk", | |
"id": 97, | |
"ifcGUID": "20Kz1qluL2Wg558svTerf5", | |
"materialName": "Holcim", | |
"kgCO2eq": 5047, | |
"volume": "5.600" | |
}, | |
{ | |
"modelId": "O96YRmBUFIk", | |
"id": 144, | |
"ifcGUID": "0vxJ9HCOfDuwHcb42u4AVr", | |
"materialName": "Steel", | |
"kgCO2eq": 615.27, | |
"volume": "0.000" | |
}, | |
{ | |
"modelId": "O96YRmBUFIk", | |
"id": 199, | |
"ifcGUID": "1j9eE0E4H4Lhvf0aOOWmMQ", | |
"materialName": "Steel", | |
"kgCO2eq": 615.27, | |
"volume": "0.011" | |
} | |
] | |
export default () => { | |
const [modelCount, setModelCount] = React.useState(0) | |
function getRandomColor() { | |
return new THREE.Color(Math.random(), Math.random(), Math.random()); | |
} | |
async function loadIfcAsFragments(path: string, ifcLoader : OBC.FragmentIfcLoader, scene: THREE.Scene) { | |
const file = await fetch(path); | |
//console.log(file) | |
const data = await file.arrayBuffer(); | |
//console.log(data) | |
const buffer = new Uint8Array(data); | |
const model = await ifcLoader.load(buffer, 'test'); | |
scene.add(model); | |
} | |
interface exIDtoFrag { | |
expressID?: string, | |
fragment?: Fragment, | |
itemIndex?: number, | |
} | |
React.useEffect(() => { | |
const colorMap: { [materialName: string]: THREE.Color } = {}; | |
TCdata.forEach(item => { | |
if (!colorMap[item.materialName]) { | |
colorMap[item.materialName] = getRandomColor(); | |
} | |
}); | |
//console.log(colorMap) | |
//#region define Viewer | |
const viewer = new OBC.Components() | |
const sceneComponent = new OBC.SimpleScene(viewer) | |
sceneComponent.setup() | |
viewer.scene = sceneComponent | |
const viewerContainer = document.getElementById("viewerContainer") as HTMLDivElement | |
const rendererComponent = new OBC.PostproductionRenderer(viewer, viewerContainer) | |
viewer.renderer = rendererComponent | |
const postproduction = rendererComponent.postproduction | |
const cameraComponent = new OBC.OrthoPerspectiveCamera(viewer) | |
viewer.camera = cameraComponent | |
const raycasterComponent = new OBC.SimpleRaycaster(viewer) | |
viewer.raycaster = raycasterComponent | |
viewer.init() | |
cameraComponent.updateAspect() | |
postproduction.enabled = true | |
const fragmentManager = new OBC.FragmentManager(viewer) | |
//console.log(fragmentManager) | |
const ifcLoader = new OBC.FragmentIfcLoader(viewer) | |
const scene = viewer.scene.get(); | |
scene.background = new THREE.Color( 0xf3f3f7 ); | |
//#endregion | |
const path = 'http://localhost:3000/SBS-2322.ifc' | |
loadIfcAsFragments(path, ifcLoader, scene).then(()=>{ | |
//mesh index equals expressId position in the array | |
const fragMap: { [expressID: string]: {fragment: Fragment,meshIndex: number} } = {}; | |
const fragmentsGroup = fragmentManager.groups[0] | |
//console.log(fragmentsGroup) | |
//SET MESH COLOURS | |
//create an array with expressId, its index in the items array and the fragment | |
for (const frag of fragmentsGroup.items){ | |
//console.log(frag) | |
for (let index = 0; index < frag.items.length; index++) { | |
fragMap[frag.items[index]] = {fragment: frag, meshIndex: index} | |
} | |
} | |
//console.log(fragMap) | |
const { properties } = OBC.IfcPropertiesManager.getIFCInfo(fragmentsGroup); | |
//console.log(properties) | |
for (const [key] of Object.entries(properties)) { | |
try{ | |
const {expressID, GlobalId} = properties[parseInt(key)]; | |
//console.log(expressID) | |
//console.log(GlobalId.value) | |
const itemData = TCdata.find(item => item.ifcGUID === GlobalId.value); | |
if (itemData){ | |
// console.log('global id', GlobalId) | |
// console.log('express id', expressID) | |
// console.log('item data', itemData) | |
//console.log('expressId', expressID, itemData) | |
const foundItem = Object.entries(fragMap).find(([x]) => x === String(expressID)); | |
if (foundItem){ | |
const color = colorMap[itemData.materialName] | |
//console.log(color) | |
//console.log('found', foundItem) | |
const {fragment, meshIndex} = foundItem[1] | |
fragment.mesh.setColorAt(meshIndex, color) | |
//console.log('composite', fragment.composites) | |
if (fragment.composites){ | |
for (let index = 1; index < fragment.composites[expressID]; index++) { | |
const compositeExpressId = expressID +'.'+ index | |
//console.log('ceid', compositeExpressId) | |
const foundItem = Object.entries(fragMap).find(([x]) => x === compositeExpressId); | |
if (foundItem){ | |
//console.log('found composite', foundItem) | |
const color = colorMap[itemData.materialName] | |
const {fragment, meshIndex} = foundItem[1] | |
fragment.mesh.setColorAt(meshIndex, color) | |
} | |
} | |
} | |
} | |
} | |
} | |
catch{} | |
//console.log('exid', expressID, 'globalid', GlobalId) | |
} | |
//get 1 item | |
// const fragment = fragmentsGroup.items[0] | |
// console.log(fragment) | |
// let color = new THREE.Color(); | |
// fragment.mesh.setColorAt(0, color.set(0xFFD966)) | |
// fragment.mesh.setColorAt(1, color.set(0x6AA84F)) | |
// fragment.mesh.setColorAt(2, color.set(0x6FA8DC)) | |
// | |
}) | |
}) | |
//#region Tentative1 | |
// React.useEffect(()=>{ | |
// const components = new OBC.Components() | |
// const sceneComponent = new OBC.SimpleScene(components) | |
// sceneComponent.setup() | |
// components.scene = sceneComponent | |
// const viewerContainer = document.getElementById("viewerContainer") as HTMLDivElement | |
// const rendererComponent = new OBC.PostproductionRenderer(components, viewerContainer) | |
// components.renderer = rendererComponent | |
// const postproduction = rendererComponent.postproduction | |
// const cameraComponent = new OBC.OrthoPerspectiveCamera(components) | |
// components.camera = cameraComponent | |
// const raycasterComponent = new OBC.SimpleRaycaster(components) | |
// components.raycaster = raycasterComponent | |
// components.init() | |
// cameraComponent.updateAspect() | |
// postproduction.enabled = true | |
// const scene = components.scene.get(); | |
// const cubes = []; | |
// const boxGeometry = new THREE.BoxGeometry(2, 2, 2); | |
// const material = new THREE.MeshLambertMaterial({ color: '#6528D7' }); | |
// const cube = new THREE.Mesh(boxGeometry, material); | |
// cube.position.x = getRandomNumber(10); | |
// cube.position.y = getRandomNumber(10); | |
// cube.position.z = getRandomNumber(10); | |
// cube.updateMatrix(); | |
// scene.add(cube); | |
// cubes.push(cube); | |
// console.log(cube) | |
// const materialManager = new OBC.MaterialManager(components); | |
// const cubeColor = new THREE.Color(0x71d728); | |
// const cubeMaterial = new THREE.MeshBasicMaterial({color: cubeColor}); | |
// materialManager.addMaterial("cubeMaterial", cubeMaterial); | |
// materialManager.addMeshes("cubeMaterial", cubes); | |
// let counter = 0 | |
// const changeCubeMaterial = () => { | |
// if (counter === 0){ | |
// materialManager.set(true, ["cubeMaterial"]); | |
// counter = 1 | |
// } | |
// else{ | |
// materialManager.set(false, ["cubeMaterial"]); | |
// counter = 0 | |
// } | |
// } | |
// viewerContainer.addEventListener('dblclick', () => OnClick()); | |
// const fragmentManager = new OBC.FragmentManager(components) | |
// console.log('fmanager', fragmentManager) | |
// const ifcLoader = new OBC.FragmentIfcLoader(components) | |
// const path = 'http://localhost:3000/Simple_project_01.ifc' | |
// const ifcmeshes: any = [] | |
// async function loadIfcAsFragments(path: string) { | |
// const file = await fetch(path); | |
// console.log(file) | |
// const data = await file.arrayBuffer(); | |
// console.log(data) | |
// const buffer = new Uint8Array(data); | |
// const model = await ifcLoader.load(buffer, 'test'); | |
// scene.add(model); | |
// console.log('model', model) | |
// console.log(model.items) | |
// const ifcInfo = OBC.IfcPropertiesManager.getIFCInfo(model); | |
// console.log('ifcinfo', ifcInfo) | |
// const { properties } = OBC.IfcPropertiesManager.getIFCInfo(model); | |
// //console.log(properties) | |
// for (const [key] of Object.entries(properties)) { | |
// //console.log(properties[parseInt(key)]) | |
// //const {expressID, GlobalId} = properties[parseInt(key)]; | |
// //console.log('frag', fragment) | |
// } | |
// const fragment = fragmentManager.list['22620']; | |
// console.log('slab', fragment) | |
// const classifier = new OBC.FragmentClassifier(components); | |
// classifier.byEntity(model); | |
// console.log('classifier', classifier) | |
// const {mesh} = model.items[2]; | |
// console.log('mesh 2', mesh) | |
// ifcmeshes.push(mesh) | |
// //const block = model.items[2].blocks | |
// //console.log('block', block) | |
// const entityData = model.data[22620]; | |
// console.log('edata', entityData) | |
// for (const key of entityData[0]) { | |
// const fragmentID = model.keyFragments[key]; | |
// console.log(fragmentID) | |
// } | |
// // for (const fragment of model.items) { | |
// // console.log(fragment) | |
// // const {mesh} = fragment; | |
// // ifcmeshes.push(mesh) | |
// // console.log('f mesh', mesh) | |
// // console.log('f items', fragment.items) | |
// // return | |
// // } | |
// } | |
// const OnClick = async () =>{ | |
// console.log('click') | |
// changeCubeMaterial() | |
// const fragments = fragmentManager | |
// const fragment = fragments.list['23620']; | |
// console.log('fragment',fragment) | |
// ifcmeshes.push(fragment) | |
// } | |
// const highlighter = new OBC.FragmentHighlighter(components) | |
// highlighter.setup() | |
// const propertiesProcessor = new OBC.IfcPropertiesProcessor(components) | |
// highlighter.events.select.onClear.add(() => { | |
// propertiesProcessor.cleanPropertiesList() | |
// }) | |
// highlighter.events.select.onHighlight.add(async (selection) => { | |
// console.log('highlight') | |
// console.log(selection); | |
// const meshes = fragmentManager.meshes; | |
// console.log(meshes) | |
// const result: any = components.raycaster.castRay(meshes); | |
// if (!result){ | |
// const mesh = result.object as FragmentMesh; | |
// console.log('mesh', mesh) | |
// ifcmeshes.push(mesh) | |
// materialManager.addMeshes("cubeMaterial", [mesh]) | |
// } | |
// console.log(result?.object) | |
// }) | |
// // let lastSelection: any; | |
// // let singleSelection = { | |
// // value: true, | |
// // }; | |
// // const highlightMaterial = new THREE.MeshBasicMaterial({ | |
// // color: '#BCF124', | |
// // depthTest: false, | |
// // opacity: 0.8, | |
// // transparent: true | |
// // }); | |
// // highlighter.add('default', [highlightMaterial]) | |
// // //highlighter.add('default', highlightMaterial); | |
// // console.log('hig', highlighter) | |
// // async function highlightOnClick(event) { | |
// // console.log('click') | |
// // const result = await highlighter.highlight('default', singleSelection.value); | |
// // console.log('sel res', result) | |
// // if (result) { | |
// // lastSelection = {}; | |
// // for (const fragment of result.fragments) { | |
// // const fragmentID = fragment.id; | |
// // console.log(fragmentID) | |
// // lastSelection[fragmentID] = [result.id]; | |
// // highlighter.highlightByID('default', lastSelection); | |
// // } | |
// // } | |
// // } | |
// // viewerContainer.addEventListener('click', (event) => highlightOnClick(event)); | |
// loadIfcAsFragments(path).then(res=>{ | |
// console.log('ifcmehs', ifcmeshes) | |
// materialManager.addMeshes("cubeMaterial", ifcmeshes) | |
// }) | |
// },[]) | |
//#endregion | |
//#region Tentative2 | |
// React.useEffect(() => { | |
// const viewer = new OBC.Components() | |
// const sceneComponent = new OBC.SimpleScene(viewer) | |
// sceneComponent.setup() | |
// viewer.scene = sceneComponent | |
// const viewerContainer = document.getElementById("viewerContainer") as HTMLDivElement | |
// const rendererComponent = new OBC.PostproductionRenderer(viewer, viewerContainer) | |
// viewer.renderer = rendererComponent | |
// const postproduction = rendererComponent.postproduction | |
// const cameraComponent = new OBC.OrthoPerspectiveCamera(viewer) | |
// viewer.camera = cameraComponent | |
// const raycasterComponent = new OBC.SimpleRaycaster(viewer) | |
// viewer.raycaster = raycasterComponent | |
// viewer.init() | |
// cameraComponent.updateAspect() | |
// postproduction.enabled = true | |
// const grid = new OBC.SimpleGrid(viewer, new THREE.Color(0x666666)) | |
// postproduction.customEffects.excludedMeshes.push(grid.get()) | |
// const fragmentManager = new OBC.FragmentManager(viewer) | |
// const ifcLoader = new OBC.FragmentIfcLoader(viewer) | |
// const highlighter = new OBC.FragmentHighlighter(viewer) | |
// highlighter.setup() | |
// const propertiesProcessor = new OBC.IfcPropertiesProcessor(viewer) | |
// highlighter.events.select.onClear.add(() => { | |
// propertiesProcessor.cleanPropertiesList() | |
// }) | |
// function download(file: File) { | |
// const link = document.createElement("a"); | |
// link.href = URL.createObjectURL(file); | |
// link.download = file.name; | |
// document.body.appendChild(link); | |
// link.click(); | |
// link.remove(); | |
// } | |
// const scene = viewer.scene.get(); | |
// scene.background = new THREE.Color( 0xf3f3f7 ); | |
// const meshes: any = []; | |
// const materialManager = new OBC.MaterialManager(viewer); | |
// async function loadIfcAsFragments(path: string) { | |
// const file = await fetch(path); | |
// console.log(file) | |
// const data = await file.arrayBuffer(); | |
// console.log(data) | |
// const buffer = new Uint8Array(data); | |
// const model = await ifcLoader.load(buffer, 'test'); | |
// scene.add(model); | |
// for (const fragment of model.items) { | |
// const {mesh} = fragment; | |
// meshes.push(mesh); | |
// console.log(mesh) | |
// } | |
// } | |
// const whiteColor = new THREE.Color("white"); | |
// const whiteMaterial = new THREE.MeshBasicMaterial({color: whiteColor}); | |
// console.log('meshes', meshes) | |
// materialManager.addMaterial("white", whiteMaterial); | |
// materialManager.addMeshes("white", meshes); | |
// const path = 'http://localhost:3000/Simple_project_01.ifc' | |
// const boxMaterial = new THREE.MeshStandardMaterial({ color: '#6528D7' }); | |
// const boxGeometry = new THREE.BoxGeometry(3, 3, 3); | |
// const cube = new THREE.Mesh(boxGeometry, boxMaterial); | |
// cube.position.set(0, 1.5, 0); | |
// scene.add(cube); | |
// loadIfcAsFragments(path).then(res=>{ | |
// console.log(res) | |
// console.log('scee model', scene.children[3]) | |
// const model = scene.children[3] as FragmentsGroup | |
// const { properties } = OBC.IfcPropertiesManager.getIFCInfo(model); | |
// console.log(properties) | |
// }) | |
// ifcLoader.onIfcLoaded.add(model => { | |
// console.log('model', model) | |
// const data = fragmentManager.export(fragmentManager.groups[0]) | |
// const blob = new Blob([data]); | |
// console.log(blob) | |
// const file = new File([blob], "small.frag"); | |
// download(file); | |
// const { properties } = OBC.IfcPropertiesManager.getIFCInfo(model); | |
// for (const [key] of Object.entries(properties)) { | |
// console.log(properties[parseInt(key)]) | |
// return | |
// try{ | |
// const {expressID, GlobalId} = properties[parseInt(key)]; | |
// console.log(expressID, GlobalId) | |
// const {mesh} = fragmentManager.list[expressID]; | |
// console.log('mesh' ,mesh) | |
// } | |
// catch(error){ | |
// console.log(error) | |
// } | |
// try{ | |
// console.log(Name.value, expressID, GlobalId.value) | |
// } | |
// catch{} | |
// } | |
// const meshes : any = []; | |
// console.log('look roof mesh') | |
// for (const fragment of model.items) { | |
// const {mesh} = fragment; | |
// console.log('loaded mesh', mesh.id, mesh) | |
// if (mesh.id === 22620){ | |
// console.log('roof mesh', mesh.id) | |
// meshes.push(mesh) | |
// } | |
// } | |
// console.log(fragmentManager.groups[0].items) | |
// setModelCount(fragmentManager.groups.length) | |
// propertiesProcessor.process(model) | |
// const classify = async () =>{ | |
// const classifier = new OBC.FragmentClassifier(viewer); | |
// classifier.byEntity(model); | |
// classifier.byStorey(model); | |
// const found = await classifier.find({entities: ["IFCSLAB"]}); | |
// console.log('**********found', found) | |
// highlighter.highlightByID('default', found); | |
// } | |
// classify(); | |
// const GetMeshById = async () =>{ | |
// const ifcmeshes = [] | |
// get all fragments | |
// const fragments = fragmentManager; | |
// select 1 fragment | |
// const meshgroup = fragments.groups[0].items[0] | |
// console.log('mgroup', meshgroup) | |
// console.log('mgroupId', meshgroup.id) | |
// console.log('ids', meshgroup.items) | |
// console.log('count of blocks', meshgroup.blocks.count) | |
// items inside the fragment | |
// const items = meshgroup.items; | |
// console.log('tems', items) | |
// const composites = meshgroup.mesh.fragment.composites["338"]; | |
// console.log('compsite', composites) | |
// const _tempMatrix = new THREE.Matrix4(); | |
// const { instanceID } = meshgroup.getInstanceAndBlockID("22620"); | |
// console.log('instance id', instanceID) | |
// const instance = meshgroup.getInstance(instanceID, _tempMatrix); | |
// console.log('instance', instance) | |
// const instance = meshgroup.mesh.fragment.getInstance(instanceID, _tempMatrix) | |
// console.log('instance', instance) | |
// const selection = meshgroup.fragments["default"]; | |
// console.log('sel', selection) | |
// selection.setInstance(0, { | |
// ids: Array.from(meshgroup.ids), | |
// transform: _tempMatrix, | |
// }); | |
// create selection map | |
// const result: FragmentIdMap = {}; | |
// const set = new Set<string> | |
// add expressId | |
// set.add("22620") | |
// meshgroup.setVisibility(false, set) | |
// const fragmGeometry = meshgroup.mesh.geometry; | |
// const index = fragmGeometry.index; | |
// result[meshgroup.id] = set; | |
// console.log('**********result', result) | |
// highlighter.highlightByID('default', result); | |
// const cubeColor = new THREE.Color(0x71d728); | |
// const cubeMaterial = new THREE.MeshBasicMaterial({color: cubeColor}); | |
// materialManager.addMaterial("cubeMaterial", cubeMaterial); | |
// const mm = materialManager.get() | |
// console.log('mmanager', mm) | |
// const subFragment = meshgroup.addFragment("cubeMaterial", [cubeMaterial]); | |
// console.log('subF', subFragment) | |
// const indices = meshgroup.mesh.geometry.index.array; | |
// console.log('indices', indices) | |
// for (let i = 0; i < indices.length - 2; i += 3) { | |
// const index = indices[i]; | |
// const blockID = meshgroup.mesh.geometry.attributes.blockID.array; | |
// console.log('block id', blockID) | |
// const block = blockID[index]; | |
// const itemID = meshgroup.mesh.fragment.getItemID(1, block); | |
// const matrix = new THREE.Matrix4() | |
// const instance = meshgroup.mesh.fragment.getInstance(1, matrix) | |
// console.log('instane', instance) | |
// console.log('idtem id', itemID) | |
// } | |
// const geometry = meshgroup.mesh.geometry; | |
// console.log('geom', geometry) | |
// for (const fragID in result) { | |
// console.log('frag Id', fragID) | |
// const fragment = fragments.list[fragID]; | |
// console.log('fragmnet', fragment) | |
// const idsNum = new Set<number>(); | |
// for (const id of result[fragID]) { | |
// styles[fragID].add(id); | |
// idsNum.add(parseInt(id, 10)); | |
// } | |
// for (const id of idsNum) { | |
// console.log('id num', idsNum) | |
// } | |
// console.log('fragment mesh', fragment.mesh) | |
// const subFragment = fragment.addFragment("cubeMaterial", [cubeMaterial]); | |
// console.log('count of blocks', fragment.blocks.count) | |
// const isBlockFragment = fragment.blocks.count > 1; | |
// console.log(isBlockFragment) | |
// let i = 0; | |
// const selection: { | |
// [selectionID: string]: FragmentIdMap; | |
// } = {}; | |
// console.log('meshcount', fragment.mesh.count) | |
// const { instanceID } = fragment.getInstanceAndBlockID("22620"); | |
// console.log('instance id', instanceID) | |
// console.log('block', fragment.blocks) | |
// const ints = fragment.getInstance(instanceID, _tempMatrix); | |
// console.log('ints', ints) | |
// console.log('subfrag', subFragment) | |
// ifcmeshes.push(fragment.mesh) | |
// subFragment.mesh.renderOrder = 2; | |
// subFragment.mesh.frustumCulled = false; | |
// } | |
// const model = fragments.groups[0]; | |
// console.log('modello', model) | |
// const idMap: OBC.FragmentIdMap = {}; | |
// const fragment = model.items[0] | |
// let color = new THREE.Color(); | |
// fragment.mesh.setColorAt(0, color.set(0xFFD966)) | |
// fragment.mesh.setColorAt(1, color.set(0x6AA84F)) | |
// fragment.mesh.setColorAt(2, color.set(0x6FA8DC)) | |
// for (const fragmentKey of model.data['22620'][0]) { | |
// console.log(fragmentKey) | |
// const fragmentId = model.keyFragments[fragmentKey]; | |
// console.log('fragId', fragmentId) | |
// const fragment = fragments.list[fragmentId]; | |
// console.log(fragment) | |
// const composites = fragment.items.filter((id) => parseInt(id, 10) === layer.expressID); | |
// idMap[fragmentId] = new Set(composites); | |
// console.log(idMap) | |
// const meshes = Object.values(fragments.list).map((frag) => | |
// frag.mesh) | |
// const instMesh = meshes[0] as THREE.InstancedMesh | |
// console.log(instMesh.count) | |
// let color = new THREE.Color(); | |
// instMesh.setColorAt(0, color.set(0xffffff)) | |
// const bufferGeom = meshes[0].geometry as THREE.BufferGeometry | |
// console.log('instacne color', meshes[0].instanceColor) | |
// if (meshes[0].instanceColor) | |
// { | |
// meshes[0].instanceColor.needsUpdate = true | |
// } | |
// console.log('firt frag mes', bufferGeom) | |
// } | |
// materialManager.addMeshes("cubeMaterial", ifcmeshes) | |
// materialManager.set(true, ["cubeMaterial"]); | |
// } | |
// GetMeshById() | |
// highlighter.events.select.onHighlight.add(async (selection) => { | |
// console.log('sel', selection) | |
// materialManager.set(true, ['whiteMaterial']) | |
// console.log('me', meshes) | |
// const fragmentID = Object.keys(selection)[0] | |
// console.log('fid', fragmentID) | |
// const expressID = Number([...selection[fragmentID]][0]) | |
// console.log('expressId', expressID) | |
// propertiesProcessor.renderProperties(model, expressID) | |
// const { name } = OBC.IfcPropertiesUtils.getEntityName(properties, expressID); | |
// const prop = properties[expressID]; | |
// console.log('name', name) | |
// console.log(prop) | |
// }) | |
// highlighter.update() | |
// }) | |
// let lastSelection : any= {}; | |
// let singleSelection = {value: true}; | |
// const highlightMaterial = new THREE.MeshBasicMaterial({ | |
// color: '#BCF124', | |
// depthTest: false, | |
// opacity: 0.8, | |
// transparent: true | |
// }); | |
// highlighter.add('default', [highlightMaterial]); | |
// highlighter.outlineMaterial.color.set(0xf0ff7a); | |
// const highlightOnClick = async () =>{ | |
// const result = await highlighter.highlight('default', singleSelection.value); | |
// console.log(result) | |
// if (result){ | |
// lastSelection = {} | |
// for (const fragment of result.fragments){ | |
// const fragmentID = fragment.id | |
// console.log(fragmentID) | |
// lastSelection[fragmentID] = [result.id]; | |
// console.log(lastSelection) | |
// } | |
// } | |
// var scene_objects = scene.children[3] as FragmentsGroup | |
// console.log('scene objects', scene_objects) | |
// const mySet = new Set<string>; | |
// mySet.add("22620") | |
// highlighter.highlightByID('default', {["ec970173-d0f3-4d0b-a827-648c6607e234"]: mySet}); | |
// highlighter.highlightByID('default', [fid]); | |
// } | |
// viewerContainer.addEventListener('click', (event) => highlightOnClick(event)); | |
// const mainToolbar = new OBC.Toolbar(viewer) | |
// mainToolbar.addChild( | |
// ifcLoader.uiElement.get("main"), | |
// propertiesProcessor.uiElement.get("main") | |
// ) | |
// viewer.ui.addToolbar(mainToolbar) | |
// }, []) | |
//#endregion | |
const viewerContainerStyle: React.CSSProperties = { | |
width: "100%", | |
height: "100%", | |
position: "relative", | |
gridArea: "viewer" | |
} | |
const titleStyle: React.CSSProperties = { | |
position: "absolute", | |
top: "15px", | |
left: "15px" | |
} | |
return ( | |
<> | |
<div id="viewerContainer" style={viewerContainerStyle}> | |
<h3 style={titleStyle}>Models loaded: {modelCount}</h3> | |
</div> | |
</> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import sys | |
import ifcopenshell | |
import ifcopenshell.api | |
import csv | |
from datetime import datetime | |
class EntityData: | |
pass | |
class TaskData: | |
pass | |
id = [] | |
instancesList = [] | |
folder = r'00-WORKING-SHARED\231213 Live Activities\\' | |
newFile = r'2200_IFC_live.ifc' | |
with open(folder+'Synchro3DObjects.csv', newline='', encoding='utf-8-sig') as csvfile: | |
excelReader = csv.reader(csvfile) | |
csv_headings = next(excelReader) | |
for row in excelReader: | |
entityInstance = EntityData() | |
for h,r in zip(csv_headings, row): | |
setattr(entityInstance, h.replace(' ','_').replace(':','_').replace('3',''), r) | |
instancesList.append(entityInstance) | |
id.append(row[1]) | |
tasksList = [] | |
with open(r'C:\temp\123\P6_Activities.csv', newline='', encoding='utf-8-sig') as csvfile: | |
excelReader = csv.reader(csvfile) | |
csv_headings = next(excelReader) | |
for row in excelReader: | |
task = TaskData() | |
for h,r in zip(csv_headings, row): | |
setattr(task, h, r) | |
tasksList.append(task) | |
for instance in instancesList: | |
task_id = instance.DUF_Task_ID.split(',') | |
savedStart = datetime(3000,1,1) | |
savedFinish = datetime(2000,1,1) | |
date_format = '%d/%m/%Y' | |
if len(task_id)==1: | |
try: | |
found_task = [t for t in tasksList if t.task_code == task_id[0]][0] | |
if found_task: | |
for prop, value in found_task.__dict__.items(): | |
setattr(instance, prop, value) | |
except Exception as error: | |
print (error) | |
else: | |
for tId in task_id: | |
try: | |
found_task = [t for t in tasksList if t.task_code == tId][0] | |
if found_task: | |
currentStart = datetime.strptime(getattr(found_task, 'ActivityStartDate'), date_format) | |
currentEnd = datetime.strptime(getattr(found_task, 'ActivityFinishDate'), date_format) | |
if currentStart < savedStart: | |
setattr(instance, 'ActivityStartDate', found_task.ActivityStartDate) | |
setattr(instance, 'TaskCodeStart', found_task.task_code) | |
savedStart = currentStart | |
setattr(instance, 'act_start_date', found_task.act_start_date) | |
if currentEnd > savedFinish: | |
setattr(instance, 'ActivityFinishDate', found_task.ActivityFinishDate) | |
setattr(instance, 'TaskCodeFinish', found_task.task_code) | |
setattr(instance, 'status_code', found_task.status_code) | |
savedFinish = currentEnd | |
setattr(instance, 'act_end_date', found_task.act_end_date) | |
#for prop, value in found_task.__dict__.items(): | |
# setattr(instance, prop, value) | |
except Exception as error: | |
print (error) | |
print (f'could not find task {tId} for instance {instance.DUF_Element_Identifier}') | |
actions = [] | |
statusActionId = '82b048b1-7f99-ee11-ab9f-0690b7055a58' | |
#prepare objects for Trimble Connect | |
for instance in instancesList: | |
try: | |
date = instance.act_start_date | |
format_date = '' | |
if date != 'NULL': | |
date_format = '%d/%m/%Y' | |
date_obj = datetime.strptime(date, date_format) | |
format_date = date_obj.strftime('%Y-%m-%d %H:%M') | |
else: | |
date_format = '%d/%m/%Y' | |
date_obj = datetime.strptime(instance.ActivityStartDate, date_format) | |
format_date = date_obj.strftime('%Y-%m-%d %H:%M') | |
# print (t.GlobalId) | |
# print (p6['start_date']) | |
actions.append({'objectId': instance.DUF_Element_Identifier, | |
'statusActionId': statusActionId, | |
"value": "Started", | |
"valueDate": format_date | |
}) | |
end_date = instance.act_end_date | |
format_end_date = '' | |
if end_date != 'NULL': | |
end_date_format = '%d/%m/%Y' | |
end_date_obj = datetime.strptime(end_date, end_date_format) | |
format_end_date = end_date_obj.strftime('%Y-%m-%d %H:%M') | |
else: | |
date_format = '%d/%m/%Y' | |
date_obj = datetime.strptime(instance.ActivityFinishDate, date_format) | |
format_end_date = date_obj.strftime('%Y-%m-%d %H:%M') | |
actions.append({'objectId': instance.DUF_Element_Identifier, | |
'statusActionId': statusActionId, | |
"value": "Completed", | |
"valueDate": format_end_date | |
}) | |
#print (f'OK {instance.DUF_Element_Identifier}') | |
except: | |
continue | |
#print (f'FAILED {instance.DUF_Element_Identifier}') | |
json_data = json.dumps(actions, default = lambda x: x.__dict__) | |
with open("actions_coolstore.json", "w") as json_file: | |
json_file.write(json_data) | |
#sys.exit("Error message") | |
#[print(t) for t in instancesList] | |
model = ifcopenshell.open(r'2200_IFC.ifc') | |
allEntities = model.by_type("IfcElement") | |
#print (allEntities) | |
results = [] | |
errors = [] | |
for t in allEntities: | |
pset = ifcopenshell.api.run("pset.add_pset", model, product=t, name="P6_Data") | |
elementId = t.Name.split(':')[-1] | |
#print(elementId) | |
try: | |
trimbleIndex = id.index(elementId) | |
currentInstance = instancesList[trimbleIndex] | |
#print (currentInstance) | |
for p in vars(currentInstance): | |
#print (p) | |
#print(vars(currentTreeData)[p]) | |
ifcopenshell.api.run("pset.edit_pset", model, pset=pset, properties={p : vars(currentInstance)[p]}) | |
results.append(t) | |
except: | |
errors.append(t) | |
model.write(folder+newFile) | |
print ('results', results) | |
print ('errors', errors) | |
print ('completed') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
import powerbi from "powerbi-visuals-api"; | |
import * as THREE from 'three'; | |
import * as OBC from 'openbim-components'; | |
import { FragmentsGroup, Fragment } from 'bim-fragment'; | |
import DataView = powerbi.DataView; | |
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions; | |
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions; | |
import IVisual = powerbi.extensibility.visual.IVisual; | |
import IViewport = powerbi.IViewport; | |
import IVisualHost = powerbi.extensibility.visual.IVisualHost; | |
import { VisualSettings } from "./settings"; | |
// Import React dependencies and the added component | |
import * as React from "react"; | |
import * as ReactDOM from "react-dom"; | |
import ReactCircleCard from "./component"; | |
import {UploadForm} from "./UploadForm" | |
import "./../style/visual.less"; | |
interface ChartDataPoint { | |
value: string; | |
category: string; | |
color: THREE.Color; | |
guid: string; | |
}; | |
export class CustomVisual implements IVisual { | |
static Config = { | |
default_color: new THREE.Color('#F5F5F5'), | |
opacity_of_unselected_objects: 0.3, | |
color1: new THREE.Color('#00FF00'), | |
color2: new THREE.Color('#FFFF00'), | |
color3: new THREE.Color('#FF0000') | |
}; | |
public host: IVisualHost; | |
private options: VisualUpdateOptions; // so we can call update from the constructor when the model is loaded TBC | |
private model_loaded: boolean = false | |
private visualSettings: VisualSettings; | |
private viewport: IViewport; | |
public scene: THREE.Scene; | |
private first_load: boolean = true; | |
private constructor_options: VisualConstructorOptions; | |
private target: HTMLElement; | |
private container!: HTMLDivElement | |
private components!: OBC.Components | |
private fragmentManager: OBC.FragmentManager | |
private highlighter: OBC.FragmentHighlighter | |
private reactRoot: React.ComponentElement<any, any>; | |
private green : THREE.Color = new THREE.Color(0x5CC45C) | |
private red: THREE.Color = new THREE.Color(0xCC0000) | |
public static Instances: CustomVisual[] = []; | |
public static Instance: CustomVisual; | |
public upload_form : UploadForm; | |
//open-bim properties | |
private fragMap: { [expressID: string]: {fragment: Fragment} } = {}; | |
private guidToexpressIdMap: { [expressID: string]: number } = {}; | |
private materialList = [] | |
constructor(options: VisualConstructorOptions) { | |
this.constructor_options = options; | |
CustomVisual.Instance = this; | |
this.host = options.host; //is this the right place to call this? | |
this.target = options.element; | |
this.first_load = true; | |
CustomVisual.Instances.push(this); | |
console.log('finish constuctor') | |
console.log('loading', this.first_load) | |
//#region create scene | |
this.container = document.createElement( 'div' ) | |
this.container.className = 'full-screen' | |
this.container.style.zIndex = '2000' | |
this.target.style.cursor = 'default' | |
this.target.appendChild( this.container ) | |
this.components = new OBC.Components(); | |
this.components.scene = new OBC.SimpleScene( this.components ); | |
this.components.renderer = new OBC.PostproductionRenderer( this.components, this.container ); | |
this.components.camera = new OBC.SimpleCamera( this.components ); | |
this.components.raycaster = new OBC.SimpleRaycaster( this.components ); | |
this.fragmentManager = new OBC.FragmentManager(this.components) | |
console.log('init component***') | |
this.components.init(); | |
( this.components.renderer as OBC.PostproductionRenderer ).postproduction.enabled = true; | |
const scene = this.components.scene.get(); | |
scene.background = new THREE.Color( 0xf3f3f7 ); | |
( this.components.camera as OBC.SimpleCamera ).controls.setLookAt( 10, 10, 10, 0, 0, 0 ); | |
//const grid = new OBC.SimpleGrid(this.components); | |
// const boxMaterial = new THREE.MeshStandardMaterial({ color: '#6528D7' }); | |
// const boxGeometry = new THREE.BoxGeometry(3, 3, 3); | |
// const cube = new THREE.Mesh(boxGeometry, boxMaterial); | |
// cube.position.set(0, 1.5, 0); | |
// scene.add(cube); | |
const directionalLight = new THREE.DirectionalLight(); | |
directionalLight.position.set( 5, 10, 3 ); | |
directionalLight.intensity = 0.5; | |
scene.add( directionalLight ); | |
const ambientLight = new THREE.AmbientLight(); | |
ambientLight.intensity = 0.5; | |
scene.add( ambientLight ); | |
this.scene = scene | |
this.highlighter = new OBC.FragmentHighlighter(this.components) | |
this.highlighter.setup() | |
//#endregion | |
// const geometry = new THREE.BoxGeometry( 10, 10, 10); | |
// const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); | |
// const cube = new THREE.Mesh( geometry, material ); | |
// scene.add( cube ); | |
//this._initScene('http://localhost:5173/SBS-2322.ifc', scene); | |
this._initScene('http://localhost:5173/CSW-2200-crop.ifc', scene); | |
} | |
//#region old update | |
// public update(options: VisualUpdateOptions) { | |
// console.log('updated, first load:', this.first_load) | |
// try{ | |
// this.viewport = options.viewport; | |
// const { width, height } = this.viewport; | |
// //console.log('w', width, 'h', height) | |
// this.options = options; // so we can call update from the constructor when the model is loaded | |
// let dataView: DataView = options.dataViews[0]; | |
// this.visualSettings = VisualSettings.parse<VisualSettings>(dataView); | |
// //console.log(dataView) | |
// if(!this.model_loaded) | |
// { | |
// console.log('model not loaded') | |
// if(this.visualSettings.model.url!="" && this.first_load) // The first load check is extremely important, otherwise the loader will be called twice and the render will freeze | |
// { | |
// //CustomVisual.Load3DModel(this.visualSettings.model.url); | |
// this._initScene('http://localhost:3000/SBS-2322.ifc'); | |
// this.first_load = false; | |
// } | |
// else if (this.first_load) | |
// { | |
// console.log('first load') | |
// // Create form to input URL. If there's already a URL defined and we're reloading the model, no input form is created, because it leads to a bug. | |
// this.reactRoot = React.createElement(UploadForm, {}); | |
// ReactDOM.render(this.reactRoot, this.target); | |
// //this._initScene(this.options) | |
// this.first_load = false; | |
// return; | |
// } else | |
// { | |
// return; | |
// } | |
// } | |
// } | |
// catch(error){ | |
// console.log(error) | |
// UploadForm.show_error_message(error); | |
// throw error; | |
// } | |
// console.log('model loaded:', this.model_loaded, 'scene defined:', this.scene) | |
// // Return if no model available | |
// if(!this.model_loaded || this.scene == undefined) // the load model process is asyncronous so we need another if | |
// { | |
// console.log('no model abvailable') | |
// return; | |
// } | |
// // Update 3D visualization | |
// console.log('Update 3D visualization') | |
// try | |
// { | |
// console.log('children', this.scene.children) | |
// //check if fragments have been loaded | |
// if (this.scene.children[3] != undefined) // beacuse of the asyncronous load process | |
// { | |
// this.visualTransform(options, this.host); | |
// } | |
// // this.renderer.setClearColor( 0xffffff, 0); | |
// // this.renderer.setSize(window.innerWidth, window.innerHeight); | |
// // this.camera.aspect = window.innerWidth/window.innerHeight; | |
// // this.camera.updateProjectionMatrix(); | |
// // CustomVisual.Instance.renderer.render(this.scene,this.camera); | |
// } | |
// catch (e) { | |
// console.error(e); | |
// UploadForm.show_error_message(e); | |
// throw e; | |
// } | |
// } | |
//#endregion | |
public update(options: VisualUpdateOptions){ | |
console.log('update') | |
//this.visualTransform(options, this.host) | |
//console.log('update this scene', this.scene) | |
var scene_objects = this.scene | |
console.log('update scene objects', scene_objects) | |
//this.visualTransform(options, this.host) | |
this.visualTransform(options, this.host) | |
} | |
private _initScene(filepath: string, scene: THREE.Scene){ | |
try{ | |
let fragmentIfcLoader = new OBC.FragmentIfcLoader(this.components); | |
fragmentIfcLoader.settings.wasm = { | |
path: "https://unpkg.com/web-ifc@0.0.43/", | |
absolute: true | |
} | |
fragmentIfcLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true; | |
fragmentIfcLoader.settings.webIfc.OPTIMIZE_PROFILES = true; | |
this.loadIfcAsFragments(filepath,this.fragmentManager, fragmentIfcLoader, scene) | |
} | |
catch{ | |
} | |
} | |
private async loadIfcAsFragments(filepath: string,fragmentManager: OBC.FragmentManager, fragmentIfcLoader: OBC.FragmentIfcLoader, scene: THREE.Scene) { | |
//const file = await fetch('../../../resources/small.ifc'); | |
const file = await fetch(filepath); | |
console.log(file) | |
const data = await file.arrayBuffer(); | |
console.log(data) | |
const buffer = new Uint8Array(data); | |
const model = await fragmentIfcLoader.load(buffer, 'test'); | |
scene.add(model); | |
console.log('model', model) | |
const fragmentsGroup = fragmentManager.groups[0] | |
const { properties } = OBC.IfcPropertiesManager.getIFCInfo(fragmentsGroup); | |
for (const [key] of Object.entries(properties)) { | |
try{ | |
//console.log(properties[parseInt(key)]) | |
const {expressID, GlobalId} = properties[parseInt(key)]; | |
if (expressID && GlobalId){ | |
this.guidToexpressIdMap[GlobalId.value] = expressID | |
} | |
} | |
catch{} | |
} | |
console.log('pmasp', this.guidToexpressIdMap) | |
for (const frag of fragmentsGroup.items){ | |
//console.log(frag) | |
for (let index = 0; index < frag.items.length; index++) { | |
this.fragMap[frag.items[index]] = {fragment: frag} | |
} | |
} | |
console.log('fragmap', this.fragMap) | |
return model | |
} | |
private visualTransform(options: VisualUpdateOptions, host: IVisualHost) { | |
this.highlighter.update() | |
//this.highlighter.clear(); | |
let dataViews = options.dataViews; | |
//console.log('dv', dataViews) | |
let categorical = dataViews[0].categorical; | |
let guid = categorical.categories[0].values; | |
//let tco2 = categorical.categories[1]; | |
let tco2 = categorical.values[0].values; | |
let volumes = categorical.values[1].values; | |
console.log('guid', guid, 'tco2', tco2) | |
const fragmentsGroup = this.scene.children[3] as FragmentsGroup | |
//console.log('fragments group', fragmentsGroup) | |
const tco2Values: {[ifcGuid: string]: number} = {} | |
for (let index = 0; index < guid.length; index++) { | |
const guidvalue = <string>guid[index] | |
//console.log(data) | |
const tco2value = <number>tco2[index] * Number.parseFloat(<string>volumes[index]) | |
//const tco2value = <number>tco2[index] | |
tco2Values[guidvalue] = tco2value | |
} | |
//we can get min and max from the measure | |
//const tco2Min = Math.min(...Object.values(tco2Values)) | |
const tco2Max = Math.max(...Object.values(tco2Values)) | |
console.log(tco2Values) | |
const percentages: number[] = [] | |
for (const item of Object.entries(tco2Values)){ | |
//console.log('item', item) | |
const expressID = this.guidToexpressIdMap[item[0]]; | |
if (expressID){ | |
const foundItem = Object.entries(this.fragMap).find(([x]) => x === String(expressID)); | |
//console.log(foundItem) | |
if (foundItem){ | |
//item co2 value/max co2 value | |
const percentage = item[1]/tco2Max | |
//console.log(percentage) | |
const colorT = new THREE.Color() | |
colorT.lerpColors(this.green, this.red, percentage) | |
//console.log(colorT) | |
if (!percentages.includes(percentage)){ | |
percentages.push(percentage) | |
this.highlighter.add(percentage.toString(), [new THREE.MeshStandardMaterial({color: colorT})]) | |
} | |
const {fragment} = foundItem[1] | |
const mybeam: OBC.FragmentIdMap = {} | |
mybeam[fragment.id] = new Set<string>(); | |
mybeam[fragment.id].add(expressID.toString()) | |
this.highlighter.highlightByID(percentage.toString(), mybeam, true) | |
//console.log(fragment) | |
} | |
} | |
} | |
console.log(percentages) | |
} | |
// private _initSceneOld(filepath: string, scene: THREE.Scene){ | |
// try{ | |
// let fragments = new OBC.FragmentManager(this.components); | |
// let fragmentIfcLoader = new OBC.FragmentIfcLoader(this.components); | |
// fragmentIfcLoader.settings.wasm = { | |
// path: "https://unpkg.com/web-ifc@0.0.43/", | |
// absolute: true | |
// } | |
// // fragmentIfcLoader.settings.wasm = { | |
// // path: "./wasm/", | |
// // absolute: true | |
// // } | |
// fragmentIfcLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true; | |
// fragmentIfcLoader.settings.webIfc.OPTIMIZE_PROFILES = true; | |
// const highlighter = new OBC.FragmentHighlighter(this.components); | |
// highlighter.update(); | |
// // const mainToolbar = new OBC.Toolbar(this.components, { name: 'Main Toolbar', position: 'bottom' }); | |
// // this.components.ui.addToolbar(mainToolbar); | |
// // const ifcButton : OBC.Button = fragmentIfcLoader.uiElement.get("main"); | |
// // mainToolbar.addChild(ifcButton); | |
// async function loadIfcAsFragments() { | |
// //const file = await fetch('../../../resources/small.ifc'); | |
// const file = await fetch(filepath); | |
// console.log(file) | |
// const data = await file.arrayBuffer(); | |
// console.log(data) | |
// const buffer = new Uint8Array(data); | |
// const model = await fragmentIfcLoader.load(buffer, 'test'); | |
// scene.add(model); | |
// console.log('model', model) | |
// return model | |
// } | |
// loadIfcAsFragments().then(model=>{ | |
// const { properties } = OBC.IfcPropertiesManager.getIFCInfo(model); | |
// //console.log(properties) | |
// for (const [key] of Object.entries(properties)) { | |
// try{ | |
// const {expressID, GlobalId} = properties[parseInt(key)]; | |
// // console.log('express id', expressID) | |
// // console.log('global id', GlobalId.value) | |
// if (expressID && GlobalId){ | |
// this.guidToexpressIdMap[GlobalId.value] = expressID | |
// } | |
// } | |
// catch{} | |
// } | |
// //create an array with expressId, its index in the items array and the fragment | |
// for (const frag of model.items){ | |
// //console.log(frag) | |
// for (let index = 0; index < frag.items.length; index++) { | |
// //this.fragMap[frag.items[index]] = {fragment: frag, meshIndex: index} | |
// } | |
// } | |
// }) | |
// for (let index = 0; index < 10; index++) { | |
// this.materialList.push(this.getRandomColor()); | |
// } | |
// // CustomVisual.Instance.model_loaded = true; | |
// // CustomVisual.Instance.first_load = false | |
// // CustomVisual.Instance.scene = scene; | |
// } | |
// catch (error){ | |
// console.log('error', error); | |
// } | |
// console.log('finish init') | |
// } | |
private getRandomColor() { | |
return new THREE.Color(Math.random(), Math.random(), Math.random()); | |
} | |
private getColumnColorByValue( | |
value: number, | |
min_value: number, | |
max_value: number | |
): THREE.Color { | |
let factor = 1.0; | |
if (max_value!=min_value) | |
{ | |
factor = (Math.round(value*100)/100-min_value)/(max_value-min_value); | |
} | |
let color = new THREE.Color(); | |
if(factor<=0.5) | |
{ | |
color = (new THREE.Color ()).lerpColors(CustomVisual.Config.color1, CustomVisual.Config.color2, 2*factor); | |
}else | |
{ | |
color = (new THREE.Color ()).lerpColors(CustomVisual.Config.color2, CustomVisual.Config.color3, 2*(factor-0.5)); | |
} | |
return color; | |
} | |
// private visualTransform2(options: VisualUpdateOptions, host: IVisualHost){ | |
// let dataViews = options.dataViews; | |
// let categorical = dataViews[0].categorical; | |
// let guid; | |
// let category; | |
// if (categorical.categories.length >1) | |
// { | |
// if(categorical.categories[0].values.length == 0 || categorical.categories[1].values.length == 0) | |
// { | |
// console.log('Some category has no values.') | |
// return; | |
// } | |
// if((categorical.categories[0].values[0])) | |
// { | |
// guid = categorical.categories[0]; | |
// category = categorical.categories[1]; | |
// }else if ((categorical.categories[1].values[0])) | |
// { | |
// guid = categorical.categories[1]; | |
// category = categorical.categories[0]; | |
// }else | |
// { | |
// console.log('No valid GUIDs imported.') | |
// return; | |
// } | |
// }else | |
// { | |
// guid = categorical.categories[0]; | |
// } | |
// console.log('category', category) | |
// console.log('guid', guid) | |
// const item = category.values[0] | |
// console.log(item) | |
// for (let index = 0; index < category.values.length; index++) { | |
// const pbcolor = this.host.colorPalette.getColor(category.values[index]); | |
// console.log('color', pbcolor) | |
// } | |
// let dataValue = undefined; | |
// let all_values; | |
// let min_value : number = 0; | |
// let max_value : number = 0; | |
// var values_by_category: { [category: string] : number; } = {}; | |
// if(dataViews[0].categorical.values) | |
// { | |
// dataValue = categorical.values[0]; | |
// console.log('data value', dataValue) | |
// all_values = dataValue.values.map(item => <number>item) | |
// console.log('all values', all_values) | |
// if (categorical.categories.length >1) | |
// { | |
// console.log('length', categorical.categories.length) | |
// for(let i = 0, len = Math.max(guid.values.length); i < len; i++) | |
// { | |
// if(values_by_category[category.values[i]]!= undefined){ | |
// values_by_category[category.values[i]] += all_values[i]; | |
// } | |
// } | |
// min_value = Math.max(values_by_category[category.values[0]],0); // to avoid negative values | |
// for (const key in values_by_category) | |
// { | |
// min_value = Math.min(values_by_category[key], min_value); | |
// max_value = Math.max(values_by_category[key], max_value); | |
// } | |
// }else | |
// { | |
// min_value = Math.min(...all_values); | |
// max_value = Math.max(...all_values); | |
// } | |
// console.log(min_value) | |
// console.log(max_value) | |
// console.log('val by cat', values_by_category) | |
// } | |
// } | |
// private visualTransformOld(options: VisualUpdateOptions, host: IVisualHost) { | |
// console.log('visual transform1') | |
// // console.log('data view', dataViews) | |
// // console.log('vt scene', this.scene) | |
// // var frag = fragmentsGroup.items[0] as Fragment | |
// // console.log('fragment', frag) | |
// // const cube = this.scene.children[3] as THREE.Mesh | |
// // cube.material = new THREE.MeshBasicMaterial({color: this.getRandomColor()}) | |
// //frag.mesh.material[0] = new THREE.MeshBasicMaterial({color: this.getRandomColor()}) | |
// // const color = this.getRandomColor() | |
// // frag.mesh.setColorAt(0, color) | |
// // frag.mesh.instanceColor.needsUpdate = true; | |
// let dataViews = options.dataViews; | |
// console.log('DV', dataViews) | |
// const fragmentsGroup = this.scene.children[3] as FragmentsGroup | |
// console.log('fragments group', fragmentsGroup) | |
// let categorical = dataViews[0].categorical; | |
// for (const frag of fragmentsGroup.items){ | |
// //console.log(frag) | |
// for (let index = 0; index < frag.items.length; index++) { | |
// this.fragMap[frag.items[index]] = {fragment: frag, meshIndex: index} | |
// } | |
// } | |
// //console.log('fmap', this.fragMap) | |
// console.log('data view', dataViews) | |
// const ifcGuids = dataViews[0].categorical.categories[0].values | |
// //console.log('ifcguids', ifcGuids) | |
// const materials = dataViews[0].categorical.categories[1].values | |
// console.log('materials', materials) | |
// const colorMap: { [materialName: string]: THREE.Color } = {}; | |
// for (let index = 0; index < materials.length; index++) { | |
// console.log('material', materials[index]) | |
// const pbcolor = this.host.colorPalette.getColor(<string>materials[index]).value; | |
// console.log(new THREE.Color(pbcolor)) | |
// if (!colorMap[materials[index].toString()]){ | |
// const pbcolor = this.host.colorPalette.getColor(<string>materials[index]).value; | |
// //colorMap[materials[index].toString()] = this.materialList[index] | |
// colorMap[materials[index].toString()] = new THREE.Color(pbcolor) | |
// } | |
// } | |
// console.log(colorMap) | |
// // materials.forEach(materials => { | |
// // if (!colorMap[m.toString()]) { | |
// // colorMap[m.toString()] = this.getRandomColor(); | |
// // } | |
// // }) | |
// const TCdata = [] | |
// // let dataValue = categorical.values[0]; | |
// // console.log('values', dataValue) | |
// // let barChartDataPoints: ChartDataPoint[] = []; | |
// // for (let i = 0, len = category.values.length; i < len; i++) { | |
// // //console.log('color', colorPalette.getColor(dataValue.values[i].toString()).value) | |
// // barChartDataPoints.push({ | |
// // category: <string>category.values[i], | |
// // value: <string>dataValue.values[i], | |
// // color: new THREE.Color(colorPalette.getColor(dataValue.values[i].toString()).value), | |
// // guid: <string>ifcGuids[i] | |
// // }); | |
// // } | |
// //console.log('chart data point', barChartDataPoints) | |
// //console.log('cpalette', colorPalette) | |
// //let color = new THREE.Color(colorPalette.getColor(categorical.categories[0].values[index].toString()).value); | |
// let category = categorical.categories[0]; | |
// console.log('cat', category) | |
// for (let index = 0; index < ifcGuids.length; index++) { | |
// TCdata.push({"ifcGUID": ifcGuids[index], "materialName": materials[index], "color": null}) | |
// } | |
// console.log('tc data', TCdata) | |
// //console.log(colorMap) | |
// const greyColor = new THREE.Color('#F5F5F5') | |
// console.log(this.fragMap) | |
// Object.entries(this.fragMap).map(x=>{ | |
// const {fragment, meshIndex} = x[1] | |
// fragment.mesh.setColorAt(meshIndex, greyColor) | |
// fragment.mesh.instanceColor.needsUpdate = true; | |
// }) | |
// if (categorical.categories.length >1) | |
// { | |
// console.log('a') | |
// } | |
// for (const item of TCdata){ | |
// //for (const item of chartDataPoints){ | |
// const expressID = this.guidToexpressIdMap[item.ifcGUID]; | |
// if (expressID){ | |
// //console.log(expressID) | |
// const foundItem = Object.entries(this.fragMap).find(([x]) => x === String(expressID)); | |
// //console.log(foundItem) | |
// if (foundItem){ | |
// const color = colorMap[item.materialName] | |
// //const color = item.color; | |
// //const color = this.getColumnColorByValue() | |
// //console.log(color) | |
// const {fragment, meshIndex} = foundItem[1] | |
// //console.log('fragment', fragment) | |
// //console.log('mindex', meshIndex) | |
// fragment.mesh.setColorAt(meshIndex, color) | |
// fragment.mesh.instanceColor.needsUpdate = true; | |
// //console.log('color', color) | |
// if (fragment.composites){ | |
// for (let index = 1; index < fragment.composites[expressID]; index++) { | |
// const compositeExpressId = expressID +'.'+ index | |
// //console.log('ceid', compositeExpressId) | |
// const foundItem = Object.entries(this.fragMap).find(([x]) => x === compositeExpressId); | |
// if (foundItem){ | |
// //console.log('found composite', foundItem) | |
// //const color = colorMap[item.materialName] | |
// //const color = item.color; | |
// const {fragment, meshIndex} = foundItem[1] | |
// fragment.mesh.setColorAt(meshIndex, color) | |
// fragment.mesh.instanceColor.needsUpdate = true; | |
// } | |
// } | |
// } | |
// } | |
// } | |
// } | |
// } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment