From c324c85086de5b9811e3385b9373088044bb128c Mon Sep 17 00:00:00 2001 From: Tom Beach Date: Tue, 12 Nov 2024 08:36:25 +0000 Subject: [PATCH 1/4] Fixes --- src/cpp/web-ifc-wasm.cpp | 2 +- src/schema-generator/gen_functional_types.ts | 2 +- .../gen_functional_types_helpers.ts | 8 +++- src/ts/ifc-schema.ts | 22 ++++----- src/ts/web-ifc-api.ts | 20 ++++---- test.ifc | 46 +++++++++++++++++++ 6 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 test.ifc diff --git a/src/cpp/web-ifc-wasm.cpp b/src/cpp/web-ifc-wasm.cpp index d737442a0..2b0ae8f64 100644 --- a/src/cpp/web-ifc-wasm.cpp +++ b/src/cpp/web-ifc-wasm.cpp @@ -392,7 +392,7 @@ bool WriteSet(uint32_t modelID, emscripten::val& val) { emscripten::val child = val[std::to_string(i)]; if (child.isNull()) loader->Push(webifc::parsing::IfcTokenType::EMPTY); - else if (child.isUndefined()) loader->Push(webifc::parsing::IfcTokenType::EMPTY); + else if (child.isUndefined()) loader->Push(webifc::parsing::IfcTokenType::UNKNOWN); else if (child.isArray()) WriteSet(modelID,child); else if (child["value"].isArray()) { diff --git a/src/schema-generator/gen_functional_types.ts b/src/schema-generator/gen_functional_types.ts index e52f97413..b6498bcc9 100644 --- a/src/schema-generator/gen_functional_types.ts +++ b/src/schema-generator/gen_functional_types.ts @@ -175,7 +175,7 @@ for (var i = 0; i < files.length; i++) { //generate ToRawLineData tsSchema.push(`ToRawLineData[${i}]={`) - for (var x=0; x < entities.length; x++) tsSchema.push(`${crc32(entities[x].name.toUpperCase(),crcTable)}:(${entities[x].derivedProps.length==0?'_:any': `i:${schemaNameClean}.${entities[x].name}`}):unknown[]=>[${entities[x].derivedProps.map((p) => generateTapeAssignment(p,types)).join(", ")}],`); + for (var x=0; x < entities.length; x++) tsSchema.push(`${crc32(entities[x].name.toUpperCase(),crcTable)}:(${entities[x].derivedProps.length==0?'_:any': `i:${schemaNameClean}.${entities[x].name}`}):unknown[]=>[${entities[x].derivedProps.map((p) => generateTapeAssignment(p,entities[x].ifcDerivedProps,types)).join(", ")}],`); tsSchema.push('}'); //initialisers diff --git a/src/schema-generator/gen_functional_types_helpers.ts b/src/schema-generator/gen_functional_types_helpers.ts index 506f821c8..3bb74aeb4 100644 --- a/src/schema-generator/gen_functional_types_helpers.ts +++ b/src/schema-generator/gen_functional_types_helpers.ts @@ -96,10 +96,14 @@ export function sortEntities(entities: Array) { return sortedEntities; } -export function generateTapeAssignment(p: Prop, types:Type[]) +export function generateTapeAssignment(p: Prop, ifcDerivedProps: string[],types:Type[]) { let type = types.find( (x:Type) => x.name == p.type); - if (p.set && type?.isSelect) + if (ifcDerivedProps.includes(p.name)) + { + return "undefined"; + } + else if (p.set && type?.isSelect) { let isEntitySelect = type?.values.some(refType => types.findIndex( t => t.name==refType)==-1); if (isEntitySelect) return `i.${p.name}`; diff --git a/src/ts/ifc-schema.ts b/src/ts/ifc-schema.ts index 0aee60aac..734463575 100644 --- a/src/ts/ifc-schema.ts +++ b/src/ts/ifc-schema.ts @@ -3209,7 +3209,7 @@ ToRawLineData[1]={ 1660063152:(i:IFC2X3.IfcRepresentationMap):unknown[]=>[i.MappingOrigin, i.MappedRepresentation], 3679540991:(i:IFC2X3.IfcRibPlateProfileProperties):unknown[]=>[i.ProfileName, i.ProfileDefinition, i.Thickness, i.RibHeight, i.RibWidth, i.RibSpacing, i.Direction], 2341007311:(i:IFC2X3.IfcRoot):unknown[]=>[i.GlobalId, i.OwnerHistory, i.Name, i.Description], -448429030:(i:IFC2X3.IfcSIUnit):unknown[]=>[i.Dimensions, i.UnitType, i.Prefix, i.Name], +448429030:(i:IFC2X3.IfcSIUnit):unknown[]=>[undefined, i.UnitType, i.Prefix, i.Name], 2042790032:(i:IFC2X3.IfcSectionProperties):unknown[]=>[i.SectionType, i.StartProfile, i.EndProfile], 4165799628:(i:IFC2X3.IfcSectionReinforcementProperties):unknown[]=>[i.LongitudinalStartPosition, i.LongitudinalEndPosition, i.TransversePosition, i.ReinforcementRole, i.SectionDefinition, i.CrossSectionReinforcementDefinitions], 867548509:(i:IFC2X3.IfcShapeAspect):unknown[]=>[i.ShapeRepresentations, i.Name, i.Description, i.ProductDefinitional, i.PartOfProductDefinitionShape], @@ -3292,7 +3292,7 @@ ToRawLineData[1]={ 1446786286:(i:IFC2X3.IfcGeneralProfileProperties):unknown[]=>[i.ProfileName, i.ProfileDefinition, i.PhysicalWeight, i.Perimeter, i.MinimumPlateThickness, i.MaximumPlateThickness, i.CrossSectionArea], 3448662350:(i:IFC2X3.IfcGeometricRepresentationContext):unknown[]=>[i.ContextIdentifier, i.ContextType, i.CoordinateSpaceDimension, i.Precision, i.WorldCoordinateSystem, i.TrueNorth], 2453401579:(_:any):unknown[]=>[], -4142052618:(i:IFC2X3.IfcGeometricRepresentationSubContext):unknown[]=>[i.ContextIdentifier, i.ContextType, i.CoordinateSpaceDimension, i.Precision, i.WorldCoordinateSystem, i.TrueNorth, i.ParentContext, i.TargetScale, i.TargetView, i.UserDefinedTargetView], +4142052618:(i:IFC2X3.IfcGeometricRepresentationSubContext):unknown[]=>[i.ContextIdentifier, i.ContextType, undefined, undefined, undefined, undefined, i.ParentContext, i.TargetScale, i.TargetView, i.UserDefinedTargetView], 3590301190:(i:IFC2X3.IfcGeometricSet):unknown[]=>[i.Elements], 178086475:(i:IFC2X3.IfcGridPlacement):unknown[]=>[i.PlacementLocation, i.PlacementRefDirection], 812098782:(i:IFC2X3.IfcHalfSpaceSolid):unknown[]=>[i.BaseSurface, i.AgreementFlag], @@ -3313,7 +3313,7 @@ ToRawLineData[1]={ 219451334:(i:IFC2X3.IfcObjectDefinition):unknown[]=>[i.GlobalId, i.OwnerHistory, i.Name, i.Description], 2833995503:(i:IFC2X3.IfcOneDirectionRepeatFactor):unknown[]=>[i.RepeatFactor], 2665983363:(i:IFC2X3.IfcOpenShell):unknown[]=>[i.CfsFaces], -1029017970:(i:IFC2X3.IfcOrientedEdge):unknown[]=>[i.EdgeStart, i.EdgeEnd, i.EdgeElement, i.Orientation], +1029017970:(i:IFC2X3.IfcOrientedEdge):unknown[]=>[undefined, undefined, i.EdgeElement, i.Orientation], 2529465313:(i:IFC2X3.IfcParameterizedProfileDef):unknown[]=>[i.ProfileType, i.ProfileName, i.Position], 2519244187:(i:IFC2X3.IfcPath):unknown[]=>[i.EdgeList], 3021840470:(i:IFC2X3.IfcPhysicalComplexQuantity):unknown[]=>[i.Name, i.Description, i.HasQuantities, i.Discrimination, i.Quality, i.Usage], @@ -11917,7 +11917,7 @@ ToRawLineData[2]={ 1660063152:(i:IFC4.IfcRepresentationMap):unknown[]=>[i.MappingOrigin, i.MappedRepresentation], 2439245199:(i:IFC4.IfcResourceLevelRelationship):unknown[]=>[i.Name, i.Description], 2341007311:(i:IFC4.IfcRoot):unknown[]=>[i.GlobalId, i.OwnerHistory, i.Name, i.Description], -448429030:(i:IFC4.IfcSIUnit):unknown[]=>[i.Dimensions, i.UnitType, i.Prefix, i.Name], +448429030:(i:IFC4.IfcSIUnit):unknown[]=>[undefined, i.UnitType, i.Prefix, i.Name], 1054537805:(i:IFC4.IfcSchedulingTime):unknown[]=>[i.Name, i.DataOrigin, i.UserDefinedDataOrigin], 867548509:(i:IFC4.IfcShapeAspect):unknown[]=>[i.ShapeRepresentations, i.Name, i.Description, {type:3,value:BooleanConvert(i.ProductDefinitional.value)}, i.PartOfProductDefinitionShape], 3982875396:(i:IFC4.IfcShapeModel):unknown[]=>[i.ContextOfItems, i.RepresentationIdentifier, i.RepresentationType, i.Items], @@ -12001,7 +12001,7 @@ ToRawLineData[2]={ 738692330:(i:IFC4.IfcFillAreaStyle):unknown[]=>[i.Name, i.FillStyles, i.ModelorDraughting == null ? null : {type:3,value:BooleanConvert(i.ModelorDraughting.value)}], 3448662350:(i:IFC4.IfcGeometricRepresentationContext):unknown[]=>[i.ContextIdentifier, i.ContextType, i.CoordinateSpaceDimension, i.Precision, i.WorldCoordinateSystem, i.TrueNorth], 2453401579:(_:any):unknown[]=>[], -4142052618:(i:IFC4.IfcGeometricRepresentationSubContext):unknown[]=>[i.ContextIdentifier, i.ContextType, i.CoordinateSpaceDimension, i.Precision, i.WorldCoordinateSystem, i.TrueNorth, i.ParentContext, i.TargetScale, i.TargetView, i.UserDefinedTargetView], +4142052618:(i:IFC4.IfcGeometricRepresentationSubContext):unknown[]=>[i.ContextIdentifier, i.ContextType, undefined, undefined, undefined, undefined, i.ParentContext, i.TargetScale, i.TargetView, i.UserDefinedTargetView], 3590301190:(i:IFC4.IfcGeometricSet):unknown[]=>[i.Elements], 178086475:(i:IFC4.IfcGridPlacement):unknown[]=>[i.PlacementLocation, i.PlacementRefDirection], 812098782:(i:IFC4.IfcHalfSpaceSolid):unknown[]=>[i.BaseSurface, {type:3,value:BooleanConvert(i.AgreementFlag.value)}], @@ -12029,11 +12029,11 @@ ToRawLineData[2]={ 3404854881:(i:IFC4.IfcMaterialProfileSetUsageTapering):unknown[]=>[i.ForProfileSet, i.CardinalPoint, i.ReferenceExtent, i.ForProfileEndSet, i.CardinalEndPoint], 3265635763:(i:IFC4.IfcMaterialProperties):unknown[]=>[i.Name, i.Description, i.Properties, i.Material], 853536259:(i:IFC4.IfcMaterialRelationship):unknown[]=>[i.Name, i.Description, i.RelatingMaterial, i.RelatedMaterials, i.Expression], -2998442950:(i:IFC4.IfcMirroredProfileDef):unknown[]=>[i.ProfileType, i.ProfileName, i.ParentProfile, i.Operator, i.Label], +2998442950:(i:IFC4.IfcMirroredProfileDef):unknown[]=>[i.ProfileType, i.ProfileName, i.ParentProfile, undefined, i.Label], 219451334:(i:IFC4.IfcObjectDefinition):unknown[]=>[i.GlobalId, i.OwnerHistory, i.Name, i.Description], 2665983363:(i:IFC4.IfcOpenShell):unknown[]=>[i.CfsFaces], 1411181986:(i:IFC4.IfcOrganizationRelationship):unknown[]=>[i.Name, i.Description, i.RelatingOrganization, i.RelatedOrganizations], -1029017970:(i:IFC4.IfcOrientedEdge):unknown[]=>[i.EdgeStart, i.EdgeEnd, i.EdgeElement, {type:3,value:BooleanConvert(i.Orientation.value)}], +1029017970:(i:IFC4.IfcOrientedEdge):unknown[]=>[undefined, undefined, i.EdgeElement, {type:3,value:BooleanConvert(i.Orientation.value)}], 2529465313:(i:IFC4.IfcParameterizedProfileDef):unknown[]=>[i.ProfileType, i.ProfileName, i.Position], 2519244187:(i:IFC4.IfcPath):unknown[]=>[i.EdgeList], 3021840470:(i:IFC4.IfcPhysicalComplexQuantity):unknown[]=>[i.Name, i.Description, i.HasQuantities, i.Discrimination, i.Quality, i.Usage], @@ -22102,7 +22102,7 @@ ToRawLineData[3]={ 1660063152:(i:IFC4X3.IfcRepresentationMap):unknown[]=>[i.MappingOrigin, i.MappedRepresentation], 2439245199:(i:IFC4X3.IfcResourceLevelRelationship):unknown[]=>[i.Name, i.Description], 2341007311:(i:IFC4X3.IfcRoot):unknown[]=>[i.GlobalId, i.OwnerHistory, i.Name, i.Description], -448429030:(i:IFC4X3.IfcSIUnit):unknown[]=>[i.Dimensions, i.UnitType, i.Prefix, i.Name], +448429030:(i:IFC4X3.IfcSIUnit):unknown[]=>[undefined, i.UnitType, i.Prefix, i.Name], 1054537805:(i:IFC4X3.IfcSchedulingTime):unknown[]=>[i.Name, i.DataOrigin, i.UserDefinedDataOrigin], 867548509:(i:IFC4X3.IfcShapeAspect):unknown[]=>[i.ShapeRepresentations, i.Name, i.Description, {type:3,value:BooleanConvert(i.ProductDefinitional.value)}, i.PartOfProductDefinitionShape], 3982875396:(i:IFC4X3.IfcShapeModel):unknown[]=>[i.ContextOfItems, i.RepresentationIdentifier, i.RepresentationType, i.Items], @@ -22190,7 +22190,7 @@ ToRawLineData[3]={ 738692330:(i:IFC4X3.IfcFillAreaStyle):unknown[]=>[i.Name, i.FillStyles, i.ModelOrDraughting == null ? null : {type:3,value:BooleanConvert(i.ModelOrDraughting.value)}], 3448662350:(i:IFC4X3.IfcGeometricRepresentationContext):unknown[]=>[i.ContextIdentifier, i.ContextType, i.CoordinateSpaceDimension, i.Precision, i.WorldCoordinateSystem, i.TrueNorth], 2453401579:(_:any):unknown[]=>[], -4142052618:(i:IFC4X3.IfcGeometricRepresentationSubContext):unknown[]=>[i.ContextIdentifier, i.ContextType, i.CoordinateSpaceDimension, i.Precision, i.WorldCoordinateSystem, i.TrueNorth, i.ParentContext, i.TargetScale, i.TargetView, i.UserDefinedTargetView], +4142052618:(i:IFC4X3.IfcGeometricRepresentationSubContext):unknown[]=>[i.ContextIdentifier, i.ContextType, undefined, undefined, undefined, undefined, i.ParentContext, i.TargetScale, i.TargetView, i.UserDefinedTargetView], 3590301190:(i:IFC4X3.IfcGeometricSet):unknown[]=>[i.Elements], 178086475:(i:IFC4X3.IfcGridPlacement):unknown[]=>[i.PlacementRelTo, i.PlacementLocation, i.PlacementRefDirection], 812098782:(i:IFC4X3.IfcHalfSpaceSolid):unknown[]=>[i.BaseSurface, {type:3,value:BooleanConvert(i.AgreementFlag.value)}], @@ -22219,12 +22219,12 @@ ToRawLineData[3]={ 3404854881:(i:IFC4X3.IfcMaterialProfileSetUsageTapering):unknown[]=>[i.ForProfileSet, i.CardinalPoint, i.ReferenceExtent, i.ForProfileEndSet, i.CardinalEndPoint], 3265635763:(i:IFC4X3.IfcMaterialProperties):unknown[]=>[i.Name, i.Description, i.Properties, i.Material], 853536259:(i:IFC4X3.IfcMaterialRelationship):unknown[]=>[i.Name, i.Description, i.RelatingMaterial, i.RelatedMaterials, i.MaterialExpression], -2998442950:(i:IFC4X3.IfcMirroredProfileDef):unknown[]=>[i.ProfileType, i.ProfileName, i.ParentProfile, i.Operator, i.Label], +2998442950:(i:IFC4X3.IfcMirroredProfileDef):unknown[]=>[i.ProfileType, i.ProfileName, i.ParentProfile, undefined, i.Label], 219451334:(i:IFC4X3.IfcObjectDefinition):unknown[]=>[i.GlobalId, i.OwnerHistory, i.Name, i.Description], 182550632:(i:IFC4X3.IfcOpenCrossProfileDef):unknown[]=>[i.ProfileType, i.ProfileName, {type:3,value:BooleanConvert(i.HorizontalWidths.value)}, i.Widths, i.Slopes, i.Tags, i.OffsetPoint], 2665983363:(i:IFC4X3.IfcOpenShell):unknown[]=>[i.CfsFaces], 1411181986:(i:IFC4X3.IfcOrganizationRelationship):unknown[]=>[i.Name, i.Description, i.RelatingOrganization, i.RelatedOrganizations], -1029017970:(i:IFC4X3.IfcOrientedEdge):unknown[]=>[i.EdgeStart, i.EdgeEnd, i.EdgeElement, {type:3,value:BooleanConvert(i.Orientation.value)}], +1029017970:(i:IFC4X3.IfcOrientedEdge):unknown[]=>[undefined, undefined, i.EdgeElement, {type:3,value:BooleanConvert(i.Orientation.value)}], 2529465313:(i:IFC4X3.IfcParameterizedProfileDef):unknown[]=>[i.ProfileType, i.ProfileName, i.Position], 2519244187:(i:IFC4X3.IfcPath):unknown[]=>[i.EdgeList], 3021840470:(i:IFC4X3.IfcPhysicalComplexQuantity):unknown[]=>[i.Name, i.Description, i.HasQuantities, i.Discrimination, i.Quality, i.Usage], diff --git a/src/ts/web-ifc-api.ts b/src/ts/web-ifc-api.ts index 36fce819c..6e1c5844e 100644 --- a/src/ts/web-ifc-api.ts +++ b/src/ts/web-ifc-api.ts @@ -26,13 +26,7 @@ declare var __WASM_PATH__:string; let WebIFCWasm: any; -if (typeof self !== 'undefined' && self.crossOriginIsolated) { - try { - WebIFCWasm = require("./web-ifc-mt"); - } catch (ex){ - WebIFCWasm = require(__WASM_PATH__); - } -} else WebIFCWasm = require(__WASM_PATH__); + export * from "./ifc-schema"; import { Properties } from "./helpers/properties"; @@ -180,7 +174,17 @@ export class IfcAPI { * @param customLocateFileHandler An optional locateFile function that let's * you override the path from which the wasm module is loaded. */ - async Init(customLocateFileHandler?: LocateFileHandlerFn) { + async Init(customLocateFileHandler?: LocateFileHandlerFn, forceSingleThread: boolean = false) { + if (!WebIFCWasm) { + if (typeof self !== 'undefined' && self.crossOriginIsolated && !forceSingleThread) { + try { + WebIFCWasm = require("./web-ifc-mt"); + } catch (ex){ + WebIFCWasm = require(__WASM_PATH__); + } + } else WebIFCWasm = require(__WASM_PATH__); + } + if (WebIFCWasm && this.wasmModule == undefined) { let locateFileHandler: LocateFileHandlerFn = (path, prefix) => { // when the wasm module requests the wasm file, we redirect to include the user specified path diff --git a/test.ifc b/test.ifc new file mode 100644 index 000000000..81259d315 --- /dev/null +++ b/test.ifc @@ -0,0 +1,46 @@ +ISO-10303-21; +HEADER; +/****************************************************** +* STEP Physical File produced by: That Open Engine WebIfc 0.0.62 +* Module: web-ifc/IfcLoader +* Version: 0.0.62 +* Source: https://github.com/ThatOpen/engine_web-ifc +* Issues: https://github.com/ThatOpen/engine_web-ifc/issues +******************************************************/ +FILE_DESCRIPTION(('1','2'),'2;1'); +FILE_NAME('test.ifc','2024-11-12T08:27:57',('3','4'),('5','6'),'thatopen/web-ifc-api','thatopen/web-ifc-api','78'); +FILE_SCHEMA(('IFC2X3')); +ENDSEC; +DATA; +#1=IFCCARTESIANPOINT((1.,2.,3.)); +#2=IFCCARTESIANPOINT((4.,5.,6.)); +#3=IFCCARTESIANPOINT((7.,8.,9.)); +#4=IFCPOLYLOOP((#1,#2,#3)); +#5=IFCFACEOUTERBOUND(#4,.T.); +#6=IFCFACE((#5)); +ENDSEC; +END-ISO-10303-21; +--------------------- +ISO-10303-21; +HEADER; +/****************************************************** +* STEP Physical File produced by: That Open Engine WebIfc 0.0.62 +* Module: web-ifc/IfcLoader +* Version: 0.0.62 +* Source: https://github.com/ThatOpen/engine_web-ifc +* Issues: https://github.com/ThatOpen/engine_web-ifc/issues +******************************************************/ +FILE_DESCRIPTION(('1','2'),'2;1'); +FILE_NAME('test.ifc','2024-11-12T08:27:57',('3','4'),('5','6'),'thatopen/web-ifc-api','thatopen/web-ifc-api','78'); +FILE_SCHEMA(('IFC2X3')); +ENDSEC; +DATA; +#7=IFCCARTESIANPOINT((1.,2.,3.)); +#8=IFCCARTESIANPOINT((4.,5.,6.)); +#9=IFCCARTESIANPOINT((7.,8.,9.)); +#10=IFCPOLYLOOP((#7,#8,#9)); +#11=IFCFACEOUTERBOUND(#10,.T.); +#12=IFCFACE((#11)); +ENDSEC; +END-ISO-10303-21; +--------------------- From db6bc70b9a785f8b469522fbb00093c321dc4ec8 Mon Sep 17 00:00:00 2001 From: Tom Beach Date: Tue, 12 Nov 2024 09:14:28 +0000 Subject: [PATCH 2/4] Fixes --- benchmark.md | 55 +++++++++++++++---------------- examples/viewer/web-ifc-viewer.ts | 2 +- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/benchmark.md b/benchmark.md index 980e66580..df59bc149 100644 --- a/benchmark.md +++ b/benchmark.md @@ -1,33 +1,32 @@ # System informations - {"cpuName":"Apple M1","freeRam":76.6875,"totalRam":8192} + {"cpuName":"Apple M1","freeRam":127.1875,"totalRam":8192} _________ | filename | Size (mb) | Time to open model (ms) | Time to execute all (ms) | Total ifc entities | Total meshes | Total geometries | total errors | |-------|-------|-------|-------|-------|-------|-------|-------| -| tests/ifcfiles/public/AC20-FZK-Haus.ifc | 2.45 | 48 | 294 | 44249 | 83 | 103 | undefined | - tests/ifcfiles/public/C20-Institute-Var-2.ifc | 10.43 | 93 | 597 | 147712 | 702 | 821 | undefined | - tests/ifcfiles/public/Element3D.ifc | 2.02 | 16 | 844 | 32875 | 1 | 5 | undefined | - tests/ifcfiles/public/FM_ARC_DigitalHub.ifc | 13.66 | 102 | 1113 | 266483 | 705 | 725 | undefined | - tests/ifcfiles/public/ISSUE_005_haus.ifc | 2.41 | 22 | 156 | 44249 | 83 | 103 | undefined | - tests/ifcfiles/public/ISSUE_021_Mini Project.ifc | 3.2 | 24 | 632 | 49044 | 2636 | 3697 | undefined | - tests/ifcfiles/public/ISSUE_034_HouseZ.ifc | 4.92 | 36 | 189 | 81806 | 228 | 239 | undefined | +| tests/ifcfiles/public/AC20-FZK-Haus.ifc | 2.45 | 32 | 317 | 44249 | 83 | 103 | undefined | + tests/ifcfiles/public/C20-Institute-Var-2.ifc | 10.43 | 88 | 1134 | 147712 | 702 | 821 | undefined | + tests/ifcfiles/public/FM_ARC_DigitalHub.ifc | 13.66 | 200 | 1407 | 266483 | 705 | 725 | undefined | + tests/ifcfiles/public/ISSUE_005_haus.ifc | 2.41 | 23 | 239 | 44249 | 83 | 103 | undefined | + tests/ifcfiles/public/ISSUE_021_Mini Project.ifc | 3.2 | 25 | 691 | 49044 | 2636 | 3697 | undefined | + tests/ifcfiles/public/ISSUE_034_HouseZ.ifc | 4.92 | 37 | 191 | 81806 | 228 | 239 | undefined | tests/ifcfiles/public/ISSUE_044_test_IFCCOMPOSITEPROFILEDEF.ifc | 0.03 | 0 | 0 | 435 | 7 | 11 | undefined | - tests/ifcfiles/public/ISSUE_053_20181220Holter_Tower_10.ifczip | 29.38 | 1452 | 11189 | 2807815 | 60285 | 60847 | undefined | - tests/ifcfiles/public/ISSUE_068_ARK_NUS_skolebygg.ifc | 54.65 | 460 | 4372 | 945194 | 4459 | 4542 | undefined | - tests/ifcfiles/public/ISSUE_102_M3D-CON-CD.ifc | 26.11 | 211 | 3052 | 503608 | 1616 | 1635 | undefined | - tests/ifcfiles/public/ISSUE_102_M3D-CON.ifc | 6.1 | 102 | 300 | 123282 | 138 | 143 | undefined | - tests/ifcfiles/public/ISSUE_126_model.ifc | 4.32 | 35 | 112 | 88876 | 257 | 288 | undefined | - tests/ifcfiles/public/ISSUE_129_N1540_17_EXE_MOD_448200_02_09_11SMC_IGC_V17.ifc | 11.67 | 88 | 711 | 202661 | 959 | 981 | undefined | - tests/ifcfiles/public/ISSUE_159_kleine_Wohnung_R22.ifc | 9.73 | 76 | 667 | 189788 | 425 | 457 | undefined | - tests/ifcfiles/public/ISSUE_171_IfcSurfaceCurveSweptAreaSolid.ifc | 0.24 | 3 | 17 | 4327 | 60 | 141 | undefined | - tests/ifcfiles/public/IfcOpenHouse_IFC4.ifc | 0.11 | 1 | 6 | 2885 | 35 | 43 | undefined | - tests/ifcfiles/public/KIT-Simple-Road-Test-Web-IFC4x3_RC2.ifc | 0.38 | 390 | 163 | 6500 | 66 | 119 | undefined | - tests/ifcfiles/public/Office_A_20110811.ifc | 3.91 | 48 | 275 | 62930 | 803 | 810 | undefined | - tests/ifcfiles/public/S_Office_Integrated Design Archi.ifc | 29.62 | 274 | 5349 | 551442 | 3418 | 3873 | undefined | - tests/ifcfiles/public/Sample_entities.ifc | 0.03 | 0 | 0 | 466 | 2 | 10 | undefined | - tests/ifcfiles/public/advanced_model.ifc | 33.67 | 310 | 2348 | 594374 | 6401 | 14120 | undefined | - tests/ifcfiles/public/dental_clinic.ifc | 12.4 | 91 | 855 | 209259 | 2586 | 2626 | undefined | - tests/ifcfiles/public/duplex.ifc | 2.27 | 18 | 67 | 38898 | 216 | 224 | undefined | - tests/ifcfiles/public/example.ifc | 0.39 | 3 | 8 | 6488 | 115 | 119 | undefined | - tests/ifcfiles/public/ifcbridge-model01.ifc | 14.47 | 180 | 281 | 296968 | 165 | 168 | undefined | - tests/ifcfiles/public/schependomlaan.ifc | 47 | 435 | 760 | 714485 | 3569 | 3643 | undefined | - tests/ifcfiles/public/tested_sample_project.ifc | 0.68 | 6 | 117 | 14119 | 93 | 98 | undefined | + tests/ifcfiles/public/ISSUE_053_20181220Holter_Tower_10.ifczip | 29.38 | 1453 | 11592 | 2807815 | 60285 | 60847 | undefined | + tests/ifcfiles/public/ISSUE_068_ARK_NUS_skolebygg.ifc | 54.65 | 644 | 4520 | 945194 | 4459 | 4542 | undefined | + tests/ifcfiles/public/ISSUE_102_M3D-CON-CD.ifc | 26.11 | 210 | 3205 | 503608 | 1616 | 1635 | undefined | + tests/ifcfiles/public/ISSUE_102_M3D-CON.ifc | 6.1 | 51 | 283 | 123282 | 138 | 143 | undefined | + tests/ifcfiles/public/ISSUE_126_model.ifc | 4.32 | 34 | 125 | 88876 | 257 | 288 | undefined | + tests/ifcfiles/public/ISSUE_129_N1540_17_EXE_MOD_448200_02_09_11SMC_IGC_V17.ifc | 11.67 | 92 | 727 | 202661 | 959 | 981 | undefined | + tests/ifcfiles/public/ISSUE_159_kleine_Wohnung_R22.ifc | 9.73 | 78 | 738 | 189788 | 425 | 457 | undefined | + tests/ifcfiles/public/ISSUE_171_IfcSurfaceCurveSweptAreaSolid.ifc | 0.24 | 2 | 20 | 4327 | 60 | 141 | undefined | + tests/ifcfiles/public/IfcOpenHouse_IFC4.ifc | 0.11 | 1 | 7 | 2885 | 35 | 43 | undefined | + tests/ifcfiles/public/KIT-Simple-Road-Test-Web-IFC4x3_RC2.ifc | 0.38 | 573 | 165 | 6500 | 66 | 119 | undefined | + tests/ifcfiles/public/Office_A_20110811.ifc | 3.91 | 44 | 459 | 62930 | 803 | 810 | undefined | + tests/ifcfiles/public/S_Office_Integrated Design Archi.ifc | 29.62 | 373 | 6904 | 551442 | 3422 | 3873 | undefined | + tests/ifcfiles/public/Sample_entities.ifc | 0.03 | 0 | 1 | 466 | 2 | 10 | undefined | + tests/ifcfiles/public/advanced_model.ifc | 33.67 | 304 | 2373 | 594374 | 6401 | 14120 | undefined | + tests/ifcfiles/public/dental_clinic.ifc | 12.4 | 93 | 886 | 209259 | 2586 | 2626 | undefined | + tests/ifcfiles/public/duplex.ifc | 2.27 | 17 | 73 | 38898 | 216 | 224 | undefined | + tests/ifcfiles/public/example.ifc | 0.39 | 4 | 8 | 6488 | 115 | 119 | undefined | + tests/ifcfiles/public/ifcbridge-model01.ifc | 14.47 | 166 | 283 | 296968 | 165 | 168 | undefined | + tests/ifcfiles/public/schependomlaan.ifc | 47 | 426 | 869 | 714485 | 3569 | 3643 | undefined | + tests/ifcfiles/public/tested_sample_project.ifc | 0.68 | 6 | 123 | 14119 | 93 | 98 | undefined | diff --git a/examples/viewer/web-ifc-viewer.ts b/examples/viewer/web-ifc-viewer.ts index 008d91e49..9ffb8262b 100644 --- a/examples/viewer/web-ifc-viewer.ts +++ b/examples/viewer/web-ifc-viewer.ts @@ -8,7 +8,7 @@ import * as ts from "typescript"; import { exampleCode } from './example'; let ifcAPI = new IfcAPI(); -ifcAPI.SetWasmPath("") +ifcAPI.SetWasmPath("./",true) let ifcThree = new IfcThree(ifcAPI); let timeout = undefined; From 6633d7407be45fb96be570e8c48af959b449b69c Mon Sep 17 00:00:00 2001 From: Tom Beach Date: Tue, 12 Nov 2024 11:05:17 +0000 Subject: [PATCH 3/4] More Fixes --- src/cpp/parsing/IfcLoader.cpp | 33 +++++++++++++++------------------ src/cpp/parsing/IfcLoader.h | 3 +-- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/cpp/parsing/IfcLoader.cpp b/src/cpp/parsing/IfcLoader.cpp index cbbb008d9..061fceb09 100644 --- a/src/cpp/parsing/IfcLoader.cpp +++ b/src/cpp/parsing/IfcLoader.cpp @@ -21,9 +21,6 @@ namespace webifc::parsing { IfcLoader::IfcLoader(uint32_t tapeSize, uint32_t memoryLimit,uint32_t lineWriterBuffer, const schema::IfcSchemaManager &schemaManager) :_lineWriterBuffer(lineWriterBuffer), _schemaManager(schemaManager) { _tokenStream = new IfcTokenStream(tapeSize,memoryLimit/tapeSize); - _nullLine = new IfcLine(); - _nullLine->ifcType=0; - _nullLine->tapeOffset=0; } const std::vector IfcLoader::GetExpressIDsWithType(const uint32_t type) const @@ -87,16 +84,21 @@ namespace webifc::parsing { output << "* Issues: https://github.com/ThatOpen/engine_web-ifc/issues" << std::endl; output << "******************************************************/" << std::endl; - const std::vector *totalLines[2] = {&_headerLines, &_lines}; uint32_t linesWritten = 0; for (uint8_t z=0; z < 2; z++) { - const std::vector* currentLines = totalLines[z]; + std::vector* currentLines; + if(z==0) currentLines= (std::vector*) &_headerLines; + else { + currentLines = new std::vector(); + std::transform( _lines.begin(), _lines.end(), std::back_inserter( *currentLines ), [](auto &kv){ return kv.second;} ); + } for(uint32_t i=0; i < currentLines->size();i++) { + IfcLine * line = (*currentLines)[i]; - if (line == _nullLine || line->ifcType == 0) continue; + if (line->ifcType == 0) continue; _tokenStream->MoveTo(line->tapeOffset); bool newLine = true; bool insideSet = false; @@ -240,7 +242,6 @@ namespace webifc::parsing { { _ifcTypeToExpressID[currentIfcType].push_back(currentExpressID); maxExpressId = std::max(maxExpressId, currentExpressID); - _lines.resize(maxExpressId,_nullLine); _lines[currentExpressID-1]=l; currentExpressID = 0; } @@ -288,7 +289,7 @@ namespace webifc::parsing { bool IfcLoader::IsValidExpressID(const uint32_t expressID) const { - if (expressID == 0 || expressID > _lines.size() || _lines[expressID-1]==_nullLine) return false; + if (expressID == 0 || expressID > _lines.size() || !_lines.contains(expressID-1)) return false; else return true; } @@ -298,27 +299,24 @@ namespace webifc::parsing { spdlog::error("[GetLineType()] Attempt to Access Invalid ExpressID {}", expressID); return 0; } - return _lines[expressID-1]->ifcType; + return _lines.at(expressID-1)->ifcType; } IfcLoader::~IfcLoader() { delete _tokenStream; for (size_t i=0; i < _lines.size();i++) { - if (_lines[i] == _nullLine) { - continue; - } + if (!_lines.contains(i)) continue; delete _lines[i]; } for (size_t i=0; i < _headerLines.size();i++) delete _headerLines[i]; _lines.clear(); _headerLines.clear(); - delete _nullLine; } void IfcLoader::MoveToLineArgument(const uint32_t expressID, const uint32_t argumentIndex) const { - _tokenStream->MoveTo(_lines[expressID-1]->tapeOffset); + _tokenStream->MoveTo(_lines.at(expressID-1)->tapeOffset); ArgumentOffset(argumentIndex); } @@ -391,8 +389,8 @@ namespace webifc::parsing { uint32_t prevLine = 0; for (size_t i=0; i < _lines.size();i++) { - if (_lines[i] == _nullLine) continue; - if (_lines[i]->tapeOffset > pos) break; + if (!_lines.contains(i)) continue; + if (_lines.at(i)->tapeOffset > pos) break; prevLine = i; } return prevLine+1; @@ -440,7 +438,6 @@ namespace webifc::parsing { line->ifcType = type; line->tapeOffset = start; //place in vector - _lines.resize(expressID,_nullLine); _lines[expressID-1]=line; _ifcTypeToExpressID[type].push_back(expressID); @@ -656,7 +653,7 @@ namespace webifc::parsing { void IfcLoader::MoveToArgumentOffset(const uint32_t expressID, const uint32_t argumentIndex) const { - _tokenStream->MoveTo(_lines[expressID-1]->tapeOffset); + _tokenStream->MoveTo(_lines.at(expressID-1)->tapeOffset); ArgumentOffset(argumentIndex); } diff --git a/src/cpp/parsing/IfcLoader.h b/src/cpp/parsing/IfcLoader.h index c1cef2782..a1c6aff63 100644 --- a/src/cpp/parsing/IfcLoader.h +++ b/src/cpp/parsing/IfcLoader.h @@ -77,8 +77,7 @@ namespace webifc::parsing const uint32_t _lineWriterBuffer; const schema::IfcSchemaManager &_schemaManager; IfcTokenStream * _tokenStream; - IfcLine * _nullLine; - std::vector _lines; + std::unordered_map _lines; std::vector _headerLines; std::unordered_map> _ifcTypeToExpressID; void ParseLines(); From 2c76b8b935116ceaf1071f28b1a3cabd6043d8f9 Mon Sep 17 00:00:00 2001 From: Tom Beach Date: Tue, 12 Nov 2024 14:15:18 +0000 Subject: [PATCH 4/4] Fixes --- src/cpp/parsing/IfcLoader.cpp | 78 +++++++++++------------------- src/cpp/parsing/IfcLoader.h | 2 +- src/cpp/web-ifc-wasm.cpp | 5 -- src/ts/web-ifc-api.ts | 2 - tests/functional/WebIfcApi.spec.ts | 18 +++---- 5 files changed, 35 insertions(+), 70 deletions(-) diff --git a/src/cpp/parsing/IfcLoader.cpp b/src/cpp/parsing/IfcLoader.cpp index 061fceb09..04a7c6eaf 100644 --- a/src/cpp/parsing/IfcLoader.cpp +++ b/src/cpp/parsing/IfcLoader.cpp @@ -21,6 +21,7 @@ namespace webifc::parsing { IfcLoader::IfcLoader(uint32_t tapeSize, uint32_t memoryLimit,uint32_t lineWriterBuffer, const schema::IfcSchemaManager &schemaManager) :_lineWriterBuffer(lineWriterBuffer), _schemaManager(schemaManager) { _tokenStream = new IfcTokenStream(tapeSize,memoryLimit/tapeSize); + _maxExpressId=0; } const std::vector IfcLoader::GetExpressIDsWithType(const uint32_t type) const @@ -218,7 +219,6 @@ namespace webifc::parsing { void IfcLoader::ParseLines() { - uint32_t maxExpressId = 0; uint32_t currentIfcType = 0; uint32_t currentExpressID = 0; uint32_t currentTapeOffset = 0; @@ -241,8 +241,8 @@ namespace webifc::parsing { else if (currentExpressID != 0) { _ifcTypeToExpressID[currentIfcType].push_back(currentExpressID); - maxExpressId = std::max(maxExpressId, currentExpressID); - _lines[currentExpressID-1]=l; + _maxExpressId = std::max(_maxExpressId, currentExpressID); + _lines[currentExpressID]=l; currentExpressID = 0; } currentIfcType = 0; @@ -284,31 +284,28 @@ namespace webifc::parsing { uint32_t IfcLoader::GetMaxExpressId() const { - return _lines.size(); + return _maxExpressId; } bool IfcLoader::IsValidExpressID(const uint32_t expressID) const { - if (expressID == 0 || expressID > _lines.size() || !_lines.contains(expressID-1)) return false; + if (expressID == 0 || expressID > _maxExpressId || !_lines.contains(expressID)) return false; else return true; } uint32_t IfcLoader::GetLineType(const uint32_t expressID) const { - if (expressID == 0 || expressID > _lines.size()) { + if (expressID == 0 || expressID > _maxExpressId || !_lines.contains(expressID)) { spdlog::error("[GetLineType()] Attempt to Access Invalid ExpressID {}", expressID); return 0; } - return _lines.at(expressID-1)->ifcType; + return _lines.at(expressID)->ifcType; } IfcLoader::~IfcLoader() { delete _tokenStream; - for (size_t i=0; i < _lines.size();i++) { - if (!_lines.contains(i)) continue; - delete _lines[i]; - } + for (const auto & [key, value] : _lines) delete value; for (size_t i=0; i < _headerLines.size();i++) delete _headerLines[i]; _lines.clear(); _headerLines.clear(); @@ -316,7 +313,8 @@ namespace webifc::parsing { void IfcLoader::MoveToLineArgument(const uint32_t expressID, const uint32_t argumentIndex) const { - _tokenStream->MoveTo(_lines.at(expressID-1)->tapeOffset); + if (!_lines.contains(expressID)) return; + _tokenStream->MoveTo(_lines.at(expressID)->tapeOffset); ArgumentOffset(argumentIndex); } @@ -385,15 +383,13 @@ namespace webifc::parsing { uint32_t IfcLoader::GetCurrentLineExpressID() const { if (_lines.size()==0) return 0; - uint32_t pos = _tokenStream->GetReadOffset(); uint32_t prevLine = 0; - for (size_t i=0; i < _lines.size();i++) - { - if (!_lines.contains(i)) continue; - if (_lines.at(i)->tapeOffset > pos) break; - prevLine = i; + uint32_t pos = _tokenStream->GetReadOffset(); + for (const auto & [key, value] : _lines) { + if (value->tapeOffset > pos) break; + prevLine = key; } - return prevLine+1; + return prevLine; } uint32_t IfcLoader::GetRefArgument() const @@ -420,17 +416,12 @@ namespace webifc::parsing { void IfcLoader::RemoveLine(const uint32_t expressID) { - _lines[expressID-1]->ifcType = 0; - } - - void IfcLoader::ExtendLineStorage(uint32_t lineStorageSize) - { - _lines.reserve(_lines.size()+lineStorageSize); + _lines.erase(expressID); } void IfcLoader::UpdateLineTape(const uint32_t expressID, const uint32_t type, const uint32_t start) { - if (expressID > _lines.size()) + if (!_lines.contains(expressID)) { // create line object IfcLine * line = new IfcLine(); @@ -438,10 +429,11 @@ namespace webifc::parsing { line->ifcType = type; line->tapeOffset = start; //place in vector - _lines[expressID-1]=line; + _lines[expressID]=line; _ifcTypeToExpressID[type].push_back(expressID); + if (expressID > _maxExpressId) _maxExpressId=expressID; - } else _lines[expressID-1]->tapeOffset = start; + } else _lines[expressID]->tapeOffset = start; } void IfcLoader::AddHeaderLineTape(const uint32_t type, const uint32_t start) @@ -653,8 +645,10 @@ namespace webifc::parsing { void IfcLoader::MoveToArgumentOffset(const uint32_t expressID, const uint32_t argumentIndex) const { - _tokenStream->MoveTo(_lines.at(expressID-1)->tapeOffset); - ArgumentOffset(argumentIndex); + if (_lines.contains(expressID)) { + _tokenStream->MoveTo(_lines.at(expressID)->tapeOffset); + ArgumentOffset(argumentIndex); + } } void IfcLoader::StepBack() const { @@ -680,30 +674,14 @@ namespace webifc::parsing { std::vector IfcLoader::GetAllLines() const { std::vector expressIDs; - auto numLines = GetMaxExpressId(); - for (uint32_t i = 1; i <= numLines; i++) - { - if (!IsValidExpressID(i)) continue; - expressIDs.push_back(i); - } + std::transform( _lines.begin(), _lines.end(), std::back_inserter( expressIDs ), [](auto &kv){ return kv.first;} ); return expressIDs; } uint32_t IfcLoader::GetNextExpressID(uint32_t expressId) const { - uint32_t currentId = expressId; - bool cont = true; - uint32_t maxId = GetMaxExpressId(); - - while(cont) - { - if(currentId > maxId) - { - cont = false; - continue; - } - currentId++; - cont = !(IsValidExpressID(currentId)); - } + uint32_t currentId = expressId+1; + while(!_lines.contains(currentId)) currentId++; return currentId; } + } \ No newline at end of file diff --git a/src/cpp/parsing/IfcLoader.h b/src/cpp/parsing/IfcLoader.h index a1c6aff63..bb9a9ec5a 100644 --- a/src/cpp/parsing/IfcLoader.h +++ b/src/cpp/parsing/IfcLoader.h @@ -61,7 +61,6 @@ namespace webifc::parsing void RemoveLine(const uint32_t expressID); void PushDouble(double input); void PushInt(int input); - void ExtendLineStorage(uint32_t lineStorageSize); uint32_t GetNextExpressID(uint32_t expressId) const; template void Push(T input) { @@ -74,6 +73,7 @@ namespace webifc::parsing uint32_t ifcType; uint32_t tapeOffset; }; + uint32_t _maxExpressId; const uint32_t _lineWriterBuffer; const schema::IfcSchemaManager &_schemaManager; IfcTokenStream * _tokenStream; diff --git a/src/cpp/web-ifc-wasm.cpp b/src/cpp/web-ifc-wasm.cpp index 2b0ae8f64..d15bd9791 100644 --- a/src/cpp/web-ifc-wasm.cpp +++ b/src/cpp/web-ifc-wasm.cpp @@ -321,10 +321,6 @@ bool ValidateExpressID(uint32_t modelID, uint32_t expressId) { return manager.IsModelOpen(modelID) ? manager.GetIfcLoader(modelID)->IsValidExpressID(expressId) : false; } -void ExtendLineStorage(uint32_t modelID, uint32_t lineStorageSize) { - if (manager.IsModelOpen(modelID)) manager.GetIfcLoader(modelID)->ExtendLineStorage(lineStorageSize); -} - uint32_t GetNextExpressID(uint32_t modelID, uint32_t expressId) { return manager.IsModelOpen(modelID) ? manager.GetIfcLoader(modelID)->GetNextExpressID(expressId) : 0; } @@ -824,7 +820,6 @@ EMSCRIPTEN_BINDINGS(my_module) { emscripten::register_vector("DoubleVector"); - emscripten::function("ExtendLineStorage", &ExtendLineStorage); emscripten::function("LoadAllGeometry", &LoadAllGeometry); emscripten::function("GetAllCrossSections", &GetAllCrossSections); emscripten::function("GetAllAlignments", &GetAllAlignments); diff --git a/src/ts/web-ifc-api.ts b/src/ts/web-ifc-api.ts index 6e1c5844e..e371f3172 100644 --- a/src/ts/web-ifc-api.ts +++ b/src/ts/web-ifc-api.ts @@ -587,7 +587,6 @@ export class IfcAPI { * @param lineObject array of line object to write */ WriteLines(modelID: number, lineObjects: Array) { - this.wasmModule.ExtendLineStorage(modelID,lineObjects.length); for (let lineObject of lineObjects) this.WriteLine(modelID,lineObject); } @@ -676,7 +675,6 @@ export class IfcAPI { /** @ignore */ WriteRawLinesData(modelID: number, data: Array) { - this.wasmModule.ExtendLineStorage(modelID,data.length); for (let rawLine of data) this.wasmModule.WriteLine(modelID, rawLine.ID, rawLine.type, rawLine.arguments); } diff --git a/tests/functional/WebIfcApi.spec.ts b/tests/functional/WebIfcApi.spec.ts index 7ed784041..fcfb7bdec 100644 --- a/tests/functional/WebIfcApi.spec.ts +++ b/tests/functional/WebIfcApi.spec.ts @@ -426,28 +426,22 @@ describe('WebIfcApi known failures', () => { describe('some use cases', () => { test("can write a new property value and read it back in", async () => { - async function getFirstStorey(api:any, mId:any) { - const storeyIds = await api.GetLineIDsWithType(mId, WebIFC.IFCBUILDINGSTOREY); - expect(storeyIds.size()).toBe(2); - const storeyId = storeyIds.get(0); - const storey = await api.properties.getItemProperties(mId, storeyId); - return [storey, storeyId]; - } - let [storey, storeyId] = await getFirstStorey(ifcApi, modelID); + + let storey = await ifcApi.properties.getItemProperties(modelID, 138); const newStoreyName = 'Nivel 1 - Editado' storey.LongName.value = newStoreyName; ifcApi.WriteLine(modelID, storey); - storey = await ifcApi.properties.getItemProperties(modelID, storeyId); + storey = await ifcApi.properties.getItemProperties(modelID, 138); expect(storey.LongName.value).toBe(newStoreyName); const writtenData = await ifcApi.SaveModel(modelID); let modelId = ifcApi.OpenModel(writtenData); - [storey, storeyId] = await getFirstStorey(ifcApi, modelId); + storey = await ifcApi.properties.getItemProperties(modelId, 138); expect(storey.LongName.value).toBe(newStoreyName); - }); - + }) }) + describe('creating ifc', () => { test('can create new ifc model', () => { let createdID = ifcApi.CreateModel({schema: WebIFC.Schemas.IFC2X3});