diff --git a/examples/Hello Wall/procedural-window-frame.ifcx b/examples/Hello Wall/procedural-window-frame.ifcx new file mode 100644 index 0000000..09d8058 --- /dev/null +++ b/examples/Hello Wall/procedural-window-frame.ifcx @@ -0,0 +1,1545 @@ +{ + "header": { + "version": "ifcx_alpha", + "author": "authorname", + "timestamp": "time string" + }, + "schemas": { + "customdata": { + "value": { + "dataType": "Object", + "objectRestrictions": { + "values": { + "originalStepInstance": { + "dataType": "String" + } + } + } + } + }, + "gltf::material": { + "value": { + "dataType": "Object", + "objectRestrictions": { + "values": { + "pbrMetallicRoughness": { + "dataType": "Object", + "optional": false, + "objectRestrictions": { + "values": { + "baseColorFactor": { + "dataType": "Array", + "optional": true, + "arrayRestrictions": { + "min": 4, + "max": 4, + "value": { + "dataType": "Real" + } + } + }, + "baseColorTexture": { + "dataType": "String", + "optional": true + }, + "metallicFactor": { + "dataType": "Real", + "optional": true + }, + "roughnessFactor": { + "dataType": "Real", + "optional": true + }, + "metallicRoughnessTexture": { + "dataType": "String", + "optional": true + } + } + } + } + }, + "normalTexture": { + "dataType": "Object", + "optional": true, + "objectRestrictions": { + "values": { + "texture": { + "dataType": "String", + "optional": false + }, + "scale": { + "dataType": "Real", + "optional": true + } + } + } + }, + "occlusionTexture": { + "dataType": "Object", + "optional": true, + "objectRestrictions": { + "values": { + "texture": { + "dataType": "String", + "optional": false + }, + "strength": { + "dataType": "Real", + "optional": true + } + } + } + }, + "emissiveTexture": { + "dataType": "String", + "optional": true + }, + "emissiveFactor": { + "dataType": "Array", + "optional": true, + "arrayRestrictions": { + "min": 3, + "max": 3, + "value": { + "dataType": "Real" + } + } + }, + "alphaMode": { + "dataType": "Enum", + "optional": true, + "enumRestrictions": { + "options": [ + "OPAQUE", + "MASK", + "BLEND" + ] + } + }, + "alphaCutoff": { + "dataType": "Real", + "optional": true + }, + "doubleSided": { + "dataType": "Boolean", + "optional": true + } + } + } + } + }, + "data": [ + { + "path": "25503984-6605-43a1-8597-eae657ff5bea", + "children": { + "Frame:Left": "bbd7f3e4-f17d-414f-947b-3b38482ffb64", + "Frame:Right": "a6bc9926-5644-4a87-9ce8-423d445fbe60", + "Frame:Top": "f016334b-6f9b-4f4f-b4f1-6ca9f40cc786", + "Glazing": "319a33df-2615-41bd-a319-925d327baf43", + "Frame:Bottom": "e0d81185-3f80-4b48-9afe-2a029aac336b" + } + }, + { + "path": "bbd7f3e4-f17d-414f-947b-3b38482ffb64", + "inherits": { + "material": "bc887b0b-aa5a-4f03-a02e-bcffc4771146" + }, + "children": { + "Body": "4dd8f80a-684f-5eae-9353-5b62db0ccad2", + "Basis": "0cc9bd50-5af1-546e-b080-a0ae35389aa7" + } + }, + { + "path": "46fca349-3364-5ca2-820d-3d0f0a094c05", + "children": { + "Profiles": "cf61a7c1-b152-50a0-ac32-5102fab4f085" + } + }, + { + "path": "0cc9bd50-5af1-546e-b080-a0ae35389aa7", + "children": { + "Body": "6a00765c-d1cb-5c9a-82cb-e7eefedf9515" + } + }, + { + "path": "cf61a7c1-b152-50a0-ac32-5102fab4f085", + "children": { + "WindowFrameProfile": "0cc9bd50-5af1-546e-b080-a0ae35389aa7" + } + }, + { + "path": "a6bc9926-5644-4a87-9ce8-423d445fbe60", + "inherits": { + "material": "bc887b0b-aa5a-4f03-a02e-bcffc4771146" + }, + "children": { + "Body": "4dd8f80a-684f-5eae-9353-5b62db0ccad2", + "Basis": "0cc9bd50-5af1-546e-b080-a0ae35389aa7" + } + }, + { + "path": "f016334b-6f9b-4f4f-b4f1-6ca9f40cc786", + "inherits": { + "material": "bc887b0b-aa5a-4f03-a02e-bcffc4771146" + }, + "children": { + "Body": "4842e51d-76f1-59fa-aede-cead4393da7f", + "Basis": "0cc9bd50-5af1-546e-b080-a0ae35389aa7" + } + }, + { + "path": "319a33df-2615-41bd-a319-925d327baf43", + "inherits": { + "material": "f8dc129a-d241-41bd-b45e-c979fe2cd601" + }, + "children": { + "Body": "e6d106c8-87b8-5cf1-9ce4-1a6401d9ba34" + } + }, + { + "path": "e0d81185-3f80-4b48-9afe-2a029aac336b", + "inherits": { + "material": "bc887b0b-aa5a-4f03-a02e-bcffc4771146" + }, + "children": { + "Body": "4842e51d-76f1-59fa-aede-cead4393da7f", + "Basis": "0cc9bd50-5af1-546e-b080-a0ae35389aa7" + } + }, + { + "path": "77e17b50-5b5a-54ff-8137-3ab205b6f5f8", + "attributes": { + "bsi::ifc::presentation::diffuseColor": [0.6,0.5,0.4], + "bsi::ifc::presentation::opacity": 0.8 + } + }, + { + "path": "14adb22b-d474-48a2-8e8f-6d4c067c1953", + "attributes": { + "customdata": { + "originalStepInstance": "#1=IfcProject('0KhR8hr7H8eewFRKm6V1bJ',$,'My Project',$,$,$,$,(#14,#26),#9)" + } + } + }, + { + "path": "14adb22b-d474-48a2-8e8f-6d4c067c1953", + "attributes": { + "bsi::ifc::class": { + "code": "IfcProject", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcProject" + } + } + }, + { + "path": "110dd47d-467b-4740-b0a7-6b2990db0700", + "attributes": { + "customdata": { + "originalStepInstance": "#1554=IfcSite('0H3THzHdj7GB2dQocGsmS0',$,'My Site',$,$,#1553,$,$,$,$,$,$,$,$)" + } + } + }, + { + "path": "110dd47d-467b-4740-b0a7-6b2990db0700", + "attributes": { + "bsi::ifc::class": { + "code": "IfcSite", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcSite" + } + } + }, + { + "path": "2f1a0d6c-7989-49ab-9927-45c0e6a871f8", + "attributes": { + "customdata": { + "originalStepInstance": "#1566=IfcBuilding('0l6WriUOb9gvadHS3cg77u',$,'My Building',$,$,#1565,$,$,$,$,$,$)" + } + } + }, + { + "path": "2f1a0d6c-7989-49ab-9927-45c0e6a871f8", + "attributes": { + "bsi::ifc::class": { + "code": "IfcBuilding", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcBuilding" + } + } + }, + { + "path": "4823712b-f19f-41bb-971e-96a178b03b3b", + "attributes": { + "customdata": { + "originalStepInstance": "#1576=IfcBuildingStorey('188t4hyPz1kvSUbg5ui3ix',$,'My Storey',$,$,#1575,$,$,$,$)" + } + } + }, + { + "path": "4823712b-f19f-41bb-971e-96a178b03b3b", + "attributes": { + "bsi::ifc::class": { + "code": "IfcBuildingStorey", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcBuildingStorey" + } + } + }, + { + "path": "cb622d10-4c98-4e36-ab2b-131c5d35297e", + "attributes": { + "customdata": { + "originalStepInstance": "#2540=IfcWindow('3BOYqGJ9XEDgih4nnTDIb_',$,$,$,$,#2575,$,$,$,$,$,$,$)" + } + } + }, + { + "path": "cb622d10-4c98-4e36-ab2b-131c5d35297e", + "attributes": { + "bsi::ifc::class": { + "code": "IfcWindow", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcWindow" + } + } + }, + { + "path": "cb622d10-4c98-4e36-ab2b-131c5d35297e", + "inherits": { + "material": "77e17b50-5b5a-54ff-8137-3ab205b6f5f8" + } + }, + { + "path": "cb622d10-4c98-4e36-ab2b-131c5d35297e", + "attributes": { + "usd::xformop": { + "transform": [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [2.66767501831055,0,1,1]] + } + } + }, + { + "path": "bbd7f3e4-f17d-414f-947b-3b38482ffb64", + "attributes": { + "customdata": { + "originalStepInstance": "#2216=IfcMember('2xr$FayNr1JvHxEpX8B$ja',$,'Unnamed',$,$,#2620,#2225,$,.BEAM.)" + } + } + }, + { + "path": "bbd7f3e4-f17d-414f-947b-3b38482ffb64", + "attributes": { + "bsi::ifc::class": { + "code": "IfcMember", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcMember" + } + } + }, + { + "path": "bbd7f3e4-f17d-414f-947b-3b38482ffb64", + "attributes": { + "usd::xformop": { + "transform": [ + [0.9999999999999848,0,-1.7484555314694896e-07,0], + [0,1,0,0], + [1.7484555314694896e-07,0,0.9999999999999848,0], + [0,0,0,1]] + } + } + }, + { + "path": "4dd8f80a-684f-5eae-9353-5b62db0ccad2", + "attributes": { + "usd::usdgeom::mesh": { + "faceVertexIndices": [0,1,2,0,2,3,23,55,21,51,55,23,52,23,24,52,51,23,53,24,25,53,52,24,54,53,25,56,21,55,26,54,25,50,54,26,27,50,26,65,47,68,65,46,47,49,50,27,28,49,27,58,49,28,48,49,58,61,56,48,61,62,56,59,48,58,31,61,48,31,48,59,67,68,22,57,58,28,29,57,28,64,61,31,66,46,65,4,5,63,4,63,64,6,66,67,45,6,7,45,7,11,45,66,6,60,31,59,44,11,10,44,45,11,43,10,9,43,44,10,42,9,8,42,43,9,41,42,8,30,57,29,30,60,57,12,41,8,40,12,20,40,41,12,32,13,4,39,20,19,39,40,20,33,14,13,33,13,32,38,19,18,38,39,19,34,15,14,34,14,33,37,18,17,37,38,18,35,16,15,35,15,34,36,17,16,36,37,17,36,16,35,5,6,67,5,67,22,22,21,63,63,21,62,62,21,56,22,63,5,30,31,60,31,32,64,64,32,4,45,46,66,47,22,68,69,71,72,70,71,69,79,80,105,102,79,105,104,105,80,81,104,80,81,107,104,103,104,107,106,107,81,77,102,103,118,81,82,118,106,81,119,82,83,119,118,82,120,83,84,120,119,83,117,84,85,117,120,84,111,85,86,111,117,85,112,111,86,87,112,86,113,112,87,88,113,87,114,113,88,89,114,88,89,115,114,90,115,89,90,116,115,91,116,90,91,110,116,92,110,91,109,110,92,121,122,108,121,108,109,133,78,132,131,132,123,131,123,124,93,124,121,74,131,124,74,124,93,101,78,133,101,129,128,101,133,129,100,128,127,100,101,128,99,127,126,99,100,127,75,131,74,75,130,131,98,126,125,98,99,126,97,98,125,97,125,130,96,130,75,96,97,130,73,74,93,76,96,75,76,73,94,95,96,76,95,76,94,78,77,108,78,108,122,78,122,123,78,123,132,77,79,102,92,93,121,92,121,109,93,94,73,107,108,77,107,77,103,134,136,137,135,136,134,138,139,140,138,140,141,143,144,145,142,143,145,146,151,155,147,155,154,147,146,155,148,154,153,148,147,154,149,153,152,149,148,153,150,149,152,157,158,159,156,157,159,160,169,175,161,175,174,161,160,175,162,174,173,162,161,174,163,173,172,163,162,173,164,163,172,165,172,171,165,164,172,166,165,171,167,171,170,167,166,171,168,167,170,177,178,179,176,177,179,181,182,183,180,181,183,185,186,187,184,185,187,188,190,191,189,190,188,193,194,195,192,193,195,196,201,205,197,205,204,197,196,205,198,204,203,198,197,204,199,203,202,199,198,203,200,199,202,209,208,207,209,207,206,213,212,211,213,211,210,216,215,214,217,216,214,221,220,218,218,220,219,231,227,222,230,231,223,231,222,223,229,230,224,230,223,224,228,229,225,229,224,225,228,225,226,235,234,233,235,233,232,239,238,236,236,238,237,243,242,241,243,241,240,247,246,245,247,245,244,250,249,248,251,250,248,255,254,252,252,254,253,259,258,257,259,257,256,263,262,261,263,261,260,266,265,264,267,266,264,271,270,269,271,269,268,274,273,272,275,274,272,279,278,276,276,278,277,283,282,281,283,281,280,287,286,284,284,286,285,291,290,289,291,289,288,307,301,292,306,307,293,307,292,293,305,306,294,306,293,294,304,305,295,305,294,295,304,295,296,303,304,297,304,296,297,303,297,298,302,303,299,303,298,299,302,299,300,311,310,309,311,309,308,321,317,312,320,321,313,321,312,313,319,320,314,320,313,314,318,319,315,319,314,315,318,315,316,325,324,323,325,323,322,328,327,326,329,328,326,330,332,333,331,332,330,336,335,334,336,337,335,339,340,341,338,339,341,343,342,344,343,344,345,346,347,348,346,348,349,351,352,353,350,351,353], + "points": [ + [7.549783e-09,0.0875,3.626432e-08], + [7.549783e-09,0,1.4628288e-08], + [7.549783e-09,0,1.2], + [7.549783e-09,0.0875,1.2], + [0.027499007,0.03,0.027499031], + [0.0025010074,0.03,0.0025010228], + [0.0025010074,-0.008788,0.0025010132], + [0.0058800075,-0.008787,0.0058800145], + [0.0082580075,-0.0084,0.008258015], + [0.007677216,-0.008568684,0.007677224], + [0.0070846938,-0.008689888,0.007084701], + [0.0064843157,-0.008762819,0.0064843227], + [0.022378007,-0.003679,0.02237802], + [0.027499007,0.003434,0.027499024], + [0.027392877,0.0021762955,0.027392894], + [0.027077336,0.00095419964,0.027077353], + [0.02656132,-0.00019767368,0.026561337], + [0.025859445,-0.0012466997,0.02585946], + [0.02499159,-0.0021631666,0.024991605], + [0.023982335,-0.0029211172,0.02398235], + [0.023202663,-0.003347671,0.023202676], + [7.549783e-09,0.0875,3.626432e-08], + [7.549783e-09,0,1.4628288e-08], + [0.015194007,0.0875,0.015194041], + [0.01813648,0.08705737,0.018136516], + [0.020818342,0.085768305,0.020818377], + [0.0219858,0.08483935,0.021985834], + [0.023002008,0.083747,0.023002043], + [0.030000007,0.075,0.030000042], + [0.05750001,0.075,0.057500053], + [0.05750001,0.055,0.05750005], + [0.030000007,0.055,0.030000038], + [0.030000007,0.003458,0.030000025], + [0.029858243,0.0017796973,0.029858261], + [0.029436806,0.00014899582,0.029436823], + [0.02874765,-0.001387839,0.028747667], + [0.027810328,-0.0027872052,0.027810343], + [0.026651433,-0.0040094005,0.02665145], + [0.025303846,-0.00501975,0.025303861], + [0.024262905,-0.005587993,0.024262918], + [0.023162007,-0.006029,0.02316202], + [0.009040007,-0.010737,0.009040015], + [0.00826732,-0.010960386,0.008267326], + [0.007479182,-0.011120972,0.0074791885], + [0.00668069,-0.011217718,0.0066806967], + [0.0058770073,-0.01125,0.005877014], + [-0.034999993,-0.01125,-0.035], + [-0.034999993,0,-0.034999996], + [0.027499007,0.057463,0.027499037], + [0.027499007,0.074176,0.027499042], + [0.021062007,0.082223,0.021062043], + [0.015205007,0.085038,0.015205041], + [0.017411945,0.0847053,0.017411979], + [0.019423543,0.08373848,0.019423578], + [0.020299409,0.08304197,0.020299442], + [0.0025010074,0.085037,0.0025010365], + [0.0025010074,0.057463,0.0025010295], + [0.05500101,0.072538,0.055001054], + [0.030000007,0.072538,0.030000042], + [0.030000007,0.057463,0.030000038], + [0.05499901,0.057463,0.05499905], + [0.027499007,0.055,0.027499037], + [0.0025010074,0.055,0.002501029], + [0.0025010074,0.0325,0.0025010235], + [0.027499007,0.0325,0.027499031], + [-0.032500993,-0.008788,-0.032501], + [7.549783e-09,-0.008788,1.2455288e-08], + [7.549783e-09,-0.002463,1.4019265e-08], + [-0.032498993,-0.002463,-0.032498997], + [0.015194007,0.0875,0.015194041], + [7.549783e-09,0.0875,3.626432e-08], + [7.549783e-09,0.0875,1.2], + [0.015194007,0.0875,1.1848061], + [0.05499901,0.057463,1.145001], + [0.030000007,0.057463,1.1700001], + [0.030000007,0.072538,1.1700001], + [0.05500101,0.072538,1.144999], + [7.549783e-09,0,1.2], + [7.549783e-09,0.0875,1.2], + [-0.034999993,0,1.235], + [-0.034999993,-0.01125,1.235], + [0.0058770073,-0.01125,1.194123], + [0.00668069,-0.011217718,1.1933193], + [0.007479182,-0.011120972,1.1925209], + [0.00826732,-0.010960386,1.1917326], + [0.009040007,-0.010737,1.19096], + [0.023162007,-0.006029,1.176838], + [0.025853062,-0.0046503283,1.174147], + [0.027650526,-0.0029819738,1.1723495], + [0.028906519,-0.0010892329,1.1710935], + [0.02958922,0.00062086154,1.1704108], + [0.029896814,0.0020246333,1.1701032], + [0.030000007,0.003458,1.1700001], + [0.030000007,0.055,1.1700001], + [0.05750001,0.055,1.1425], + [0.05750001,0.075,1.1425], + [0.030000007,0.075,1.1700001], + [0.023002008,0.083747,1.176998], + [0.02106273,0.085596636,1.1789373], + [0.018701779,0.08686465,1.1812983], + [0.01697644,0.08733994,1.1830236], + [0.015194007,0.0875,1.1848061], + [-0.032498993,-0.002463,1.232499], + [7.549783e-09,-0.002463,1.2], + [7.549783e-09,-0.008788,1.2], + [-0.032500993,-0.008788,1.232501], + [0.0058800075,-0.008787,1.19412], + [0.0025010074,-0.008788,1.197499], + [0.0025010074,0.03,1.197499], + [0.027499007,0.03,1.1725011], + [0.027499007,0.003434,1.172501], + [0.022378007,-0.003679,1.177622], + [0.024393674,-0.0026439307,1.1756064], + [0.02573978,-0.0013927278,1.1742603], + [0.02668028,2.6147964e-05,1.1733197], + [0.027191456,0.0013078401,1.1728085], + [0.027421756,0.0023598508,1.1725782], + [0.0082580075,-0.0084,1.1917421], + [0.0064843157,-0.008762819,1.1935157], + [0.0070846938,-0.008689888,1.1929153], + [0.007677216,-0.008568684,1.1923229], + [0.027499007,0.0325,1.1725011], + [0.0025010074,0.0325,1.197499], + [0.0025010074,0.055,1.197499], + [0.027499007,0.055,1.1725011], + [0.021062007,0.082223,1.178938], + [0.019606877,0.08360976,1.1803932], + [0.017835936,0.08456071,1.1821641], + [0.016541893,0.084917426,1.1834582], + [0.015205007,0.085038,1.184795], + [0.027499007,0.074176,1.1725011], + [0.027499007,0.057463,1.1725011], + [0.0025010074,0.057463,1.197499], + [0.0025010074,0.085037,1.197499], + [7.549783e-09,0,1.4628288e-08], + [-0.034999993,0,-0.034999996], + [-0.034999993,0,1.235], + [7.549783e-09,0,1.2], + [-0.034999993,0,-0.034999996], + [-0.034999993,-0.01125,-0.035], + [-0.034999993,-0.01125,1.235], + [-0.034999993,0,1.235], + [-0.034999993,-0.01125,-0.035], + [0.0058770073,-0.01125,0.005877014], + [0.0058770073,-0.01125,1.194123], + [-0.034999993,-0.01125,1.235], + [0.009040007,-0.010737,0.009040015], + [0.00826732,-0.010960386,0.008267326], + [0.007479182,-0.011120972,0.0074791885], + [0.00668069,-0.011217718,0.0066806967], + [0.0058770073,-0.01125,0.005877014], + [0.009040007,-0.010737,1.19096], + [0.0058770073,-0.01125,1.194123], + [0.00668069,-0.011217718,1.1933193], + [0.007479182,-0.011120972,1.1925209], + [0.00826732,-0.010960386,1.1917326], + [0.009040007,-0.010737,0.009040015], + [0.023162007,-0.006029,0.02316202], + [0.023162007,-0.006029,1.176838], + [0.009040007,-0.010737,1.19096], + [0.030000007,0.003458,0.030000025], + [0.029858243,0.0017796973,0.029858261], + [0.029436806,0.00014899582,0.029436823], + [0.02874765,-0.001387839,0.028747667], + [0.027810328,-0.0027872052,0.027810343], + [0.026651433,-0.0040094005,0.02665145], + [0.025303846,-0.00501975,0.025303861], + [0.024262905,-0.005587993,0.024262918], + [0.023162007,-0.006029,0.02316202], + [0.030000007,0.003458,1.1700001], + [0.023162007,-0.006029,1.176838], + [0.025853062,-0.0046503283,1.174147], + [0.027650526,-0.0029819738,1.1723495], + [0.028906519,-0.0010892329,1.1710935], + [0.02958922,0.00062086154,1.1704108], + [0.029896814,0.0020246333,1.1701032], + [0.030000007,0.003458,0.030000025], + [0.030000007,0.055,0.030000038], + [0.030000007,0.055,1.1700001], + [0.030000007,0.003458,1.1700001], + [0.030000007,0.055,0.030000038], + [0.05750001,0.055,0.05750005], + [0.05750001,0.055,1.1425], + [0.030000007,0.055,1.1700001], + [0.05750001,0.055,0.05750005], + [0.05750001,0.075,0.057500053], + [0.05750001,0.075,1.1425], + [0.05750001,0.055,1.1425], + [0.05750001,0.075,0.057500053], + [0.030000007,0.075,0.030000042], + [0.030000007,0.075,1.1700001], + [0.05750001,0.075,1.1425], + [0.030000007,0.075,0.030000042], + [0.023002008,0.083747,0.023002043], + [0.023002008,0.083747,1.176998], + [0.030000007,0.075,1.1700001], + [0.015194007,0.0875,0.015194041], + [0.01813648,0.08705737,0.018136516], + [0.020818342,0.085768305,0.020818377], + [0.0219858,0.08483935,0.021985834], + [0.023002008,0.083747,0.023002043], + [0.015194007,0.0875,1.1848061], + [0.023002008,0.083747,1.176998], + [0.02106273,0.085596636,1.1789373], + [0.018701779,0.08686465,1.1812983], + [0.01697644,0.08733994,1.1830236], + [0.027499007,0.057463,0.027499037], + [0.027499007,0.074176,0.027499042], + [0.027499007,0.074176,1.1725011], + [0.027499007,0.057463,1.1725011], + [0.0025010074,0.057463,0.0025010295], + [0.027499007,0.057463,0.027499037], + [0.027499007,0.057463,1.1725011], + [0.0025010074,0.057463,1.197499], + [0.0025010074,0.085037,0.0025010365], + [0.0025010074,0.057463,0.0025010295], + [0.0025010074,0.057463,1.197499], + [0.0025010074,0.085037,1.197499], + [0.015205007,0.085038,0.015205041], + [0.0025010074,0.085037,0.0025010365], + [0.0025010074,0.085037,1.197499], + [0.015205007,0.085038,1.184795], + [0.015205007,0.085038,0.015205041], + [0.017411945,0.0847053,0.017411979], + [0.019423543,0.08373848,0.019423578], + [0.020299409,0.08304197,0.020299442], + [0.021062007,0.082223,0.021062043], + [0.015205007,0.085038,1.184795], + [0.021062007,0.082223,1.178938], + [0.019606877,0.08360976,1.1803932], + [0.017835936,0.08456071,1.1821641], + [0.016541893,0.084917426,1.1834582], + [0.027499007,0.074176,0.027499042], + [0.021062007,0.082223,0.021062043], + [0.021062007,0.082223,1.178938], + [0.027499007,0.074176,1.1725011], + [0.05500101,0.072538,0.055001054], + [0.030000007,0.072538,0.030000042], + [0.030000007,0.072538,1.1700001], + [0.05500101,0.072538,1.144999], + [0.05499901,0.057463,0.05499905], + [0.05500101,0.072538,0.055001054], + [0.05500101,0.072538,1.144999], + [0.05499901,0.057463,1.145001], + [0.030000007,0.057463,0.030000038], + [0.05499901,0.057463,0.05499905], + [0.05499901,0.057463,1.145001], + [0.030000007,0.057463,1.1700001], + [0.030000007,0.072538,0.030000042], + [0.030000007,0.057463,0.030000038], + [0.030000007,0.057463,1.1700001], + [0.030000007,0.072538,1.1700001], + [0.027499007,0.055,0.027499037], + [0.0025010074,0.055,0.002501029], + [0.0025010074,0.055,1.197499], + [0.027499007,0.055,1.1725011], + [0.027499007,0.0325,0.027499031], + [0.027499007,0.055,0.027499037], + [0.027499007,0.055,1.1725011], + [0.027499007,0.0325,1.1725011], + [0.0025010074,0.0325,0.0025010235], + [0.027499007,0.0325,0.027499031], + [0.027499007,0.0325,1.1725011], + [0.0025010074,0.0325,1.197499], + [0.0025010074,0.055,0.002501029], + [0.0025010074,0.0325,0.0025010235], + [0.0025010074,0.0325,1.197499], + [0.0025010074,0.055,1.197499], + [-0.032500993,-0.008788,-0.032501], + [7.549783e-09,-0.008788,1.2455288e-08], + [7.549783e-09,-0.008788,1.2], + [-0.032500993,-0.008788,1.232501], + [-0.032498993,-0.002463,-0.032498997], + [-0.032500993,-0.008788,-0.032501], + [-0.032500993,-0.008788,1.232501], + [-0.032498993,-0.002463,1.232499], + [7.549783e-09,-0.002463,1.4019265e-08], + [-0.032498993,-0.002463,-0.032498997], + [-0.032498993,-0.002463,1.232499], + [7.549783e-09,-0.002463,1.2], + [7.549783e-09,-0.008788,1.2455288e-08], + [7.549783e-09,-0.002463,1.4019265e-08], + [7.549783e-09,-0.002463,1.2], + [7.549783e-09,-0.008788,1.2], + [0.027499007,0.03,0.027499031], + [0.0025010074,0.03,0.0025010228], + [0.0025010074,0.03,1.197499], + [0.027499007,0.03,1.1725011], + [0.027499007,0.003434,0.027499024], + [0.027499007,0.03,0.027499031], + [0.027499007,0.03,1.1725011], + [0.027499007,0.003434,1.172501], + [0.027499007,0.003434,0.027499024], + [0.027392877,0.0021762955,0.027392894], + [0.027077336,0.00095419964,0.027077353], + [0.02656132,-0.00019767368,0.026561337], + [0.025859445,-0.0012466997,0.02585946], + [0.02499159,-0.0021631666,0.024991605], + [0.023982335,-0.0029211172,0.02398235], + [0.023202663,-0.003347671,0.023202676], + [0.022378007,-0.003679,0.02237802], + [0.027499007,0.003434,1.172501], + [0.022378007,-0.003679,1.177622], + [0.024393674,-0.0026439307,1.1756064], + [0.02573978,-0.0013927278,1.1742603], + [0.02668028,2.6147964e-05,1.1733197], + [0.027191456,0.0013078401,1.1728085], + [0.027421756,0.0023598508,1.1725782], + [0.0082580075,-0.0084,0.008258015], + [0.022378007,-0.003679,0.02237802], + [0.022378007,-0.003679,1.177622], + [0.0082580075,-0.0084,1.1917421], + [0.0082580075,-0.0084,0.008258015], + [0.007677216,-0.008568684,0.007677224], + [0.0070846938,-0.008689888,0.007084701], + [0.0064843157,-0.008762819,0.0064843227], + [0.0058800075,-0.008787,0.0058800145], + [0.0082580075,-0.0084,1.1917421], + [0.0058800075,-0.008787,1.19412], + [0.0064843157,-0.008762819,1.1935157], + [0.0070846938,-0.008689888,1.1929153], + [0.007677216,-0.008568684,1.1923229], + [0.0025010074,-0.008788,0.0025010132], + [0.0058800075,-0.008787,0.0058800145], + [0.0058800075,-0.008787,1.19412], + [0.0025010074,-0.008788,1.197499], + [0.0025010074,0.03,0.0025010228], + [0.0025010074,-0.008788,0.0025010132], + [0.0025010074,-0.008788,1.197499], + [0.0025010074,0.03,1.197499], + [0.05750001,0.01625,0.05750004], + [0.031000007,0.01625,0.03100003], + [0.031000007,0.01625,1.169], + [0.05750001,0.01625,1.1425], + [0.05750001,0.01625,0.05750004], + [0.031000007,0.01625,0.03100003], + [0.05750001,0.00625,0.05750004], + [0.031000007,0.00625,0.031000026], + [0.05750001,0.00625,0.05750004], + [0.05750001,0.01625,0.05750004], + [0.05750001,0.01625,1.1425], + [0.05750001,0.00625,1.1425], + [0.031000007,0.01625,1.169], + [0.05750001,0.01625,1.1425], + [0.031000007,0.00625,1.169], + [0.05750001,0.00625,1.1425], + [0.031000007,0.01625,0.03100003], + [0.031000007,0.00625,0.031000026], + [0.031000007,0.00625,1.169], + [0.031000007,0.01625,1.169], + [0.031000007,0.00625,0.031000026], + [0.05750001,0.00625,0.05750004], + [0.05750001,0.00625,1.1425], + [0.031000007,0.00625,1.169]] + } + } + }, + { + "path": "0cc9bd50-5af1-546e-b080-a0ae35389aa7", + "attributes": { + "bsi::ifc::procedural_geometry": { + "has_profile": { + "bsi::ifc::geometry::procedural::composite_profile": { + "Profiles": [ + { + "bsi::ifc::geometry::procedural::rectangle": { + "position": { + "Location": [0.0442500002682209,0.011249999748542931] + }, + "Width": 0.0265000015497208, + "Height": 0.00999999931082134 + } + }, + { + "bsi::ifc::geometry::procedural::profile_with_voids": { + "exterior": { + "bsi::ifc::geometry::procedural::composite_curve": { + "Segments": [ + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.0,0.0], + [0.0,0.0874999985098839], + [0.0151939997449517,0.0874999985098839]] + } + }, + { + "bsi::ifc::geometry::procedural::circular_arc": { + "Points": [ + [0.0151939997449517,0.0874999985098839], + [0.010863697832381853,0.06849228243041633], + [0.0230020005255938,0.083746999502182]] + } + }, + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.0230020005255938,0.083746999502182], + [0.0299999993294477,0.0750000029802322], + [0.0575000010430813,0.0750000029802322], + [0.0575000010430813,0.0549999997019768], + [0.0299999993294477,0.0549999997019768], + [0.0299999993294477,0.00345800002105534]] + } + }, + { + "bsi::ifc::geometry::procedural::circular_arc": { + "Points": [ + [0.0299999993294477,0.00345800002105534], + [0.011888724188539031,0.009304335612320332], + [0.0231619998812675,-0.00602900004014373]] + } + }, + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.0231619998812675,-0.00602900004014373], + [0.00903999991714954,-0.0107370000332594]] + } + }, + { + "bsi::ifc::geometry::procedural::circular_arc": { + "Points": [ + [0.00903999991714954,-0.0107370000332594], + [0.00427618375762478,0.008627665566564873], + [0.00587699981406331,-0.0112500004470348]] + } + }, + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.00587699981406331,-0.0112500004470348], + [-0.0350000001490116,-0.0112500004470348], + [-0.0350000001490116,0.0], + [0.0,0.0]] + } + }] + } + }, + "Interior": [ + { + "bsi::ifc::geometry::procedural::composite_curve": { + "Segments": [ + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.00250099995173514,0.0299999993294477], + [0.0274989996105433,0.0299999993294477], + [0.0274989996105433,0.00343400007113814]] + } + }, + { + "bsi::ifc::geometry::procedural::circular_arc": { + "Points": [ + [0.0274989996105433,0.00343400007113814], + [0.013912756499950347,0.00781547697836013], + [0.0223779994994402,-0.00367900007404387]] + } + }, + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.0223779994994402,-0.00367900007404387], + [0.00825800001621246,-0.00839999970048666]] + } + }, + { + "bsi::ifc::geometry::procedural::circular_arc": { + "Points": [ + [0.00825800001621246,-0.00839999970048666], + [0.004682075312131946,0.006073446219056597], + [0.00588000006973743,-0.00878699962049723]] + } + }, + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.00588000006973743,-0.00878699962049723], + [0.00250099995173514,-0.00878799986094236], + [0.00250099995173514,0.0299999993294477]] + } + }] + } + }, + { + "bsi::ifc::geometry::procedural::composite_curve": { + "Segments": [ + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.0274989996105433,0.0741759985685349], + [0.0274989996105433,0.057463001459837], + [0.00250099995173514,0.057463001459837], + [0.00250099995173514,0.085037000477314], + [0.0152049995958805,0.085037998855114]] + } + }, + { + "bsi::ifc::geometry::procedural::circular_arc": { + "Points": [ + [0.0152049995958805,0.085037998855114], + [0.011949780623431685,0.07076441181627047], + [0.0210619997233152,0.0822229981422424]] + } + }, + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.0210619997233152,0.0822229981422424], + [0.0274989996105433,0.0741759985685349]] + } + }] + } + }, + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.0,-0.00878799986094236], + [-0.0325010009109974,-0.00878799986094236], + [-0.0324990004301071,-0.00246299989521503], + [0.0,-0.00246299989521503], + [0.0,-0.00878799986094236]] + } + }, + { + "bsi::ifc::geometry::procedural::rectangle": { + "position": { + "Location": [0.01499999978113922,0.04374999925494195] + }, + "Width": 0.02499799965880816, + "Height": 0.0225000008940697 + } + }, + { + "bsi::ifc::geometry::procedural::polyline": { + "Points": [ + [0.0299999993294477,0.0725380033254623], + [0.0550010018050671,0.0725380033254623], + [0.0549990013241768,0.057463001459837], + [0.0299999993294477,0.057463001459837], + [0.0299999993294477,0.0725380033254623]] + } + }] + } + }] + } + } + } + } + }, + { + "path": "6a00765c-d1cb-5c9a-82cb-e7eefedf9515", + "attributes": { + "usd::usdgeom::mesh": { + "faceVertexIndices": [33,14,15,34,15,16,34,33,15,32,13,14,32,14,33,29,34,16,31,12,13,31,13,32,30,11,12,30,12,31,17,29,16,26,17,18,26,29,17,27,26,18,28,18,19,28,27,18,25,19,20,25,28,19,23,25,20,46,23,20,45,23,46,35,11,30,56,8,9,56,9,55,21,46,20,21,48,46,10,55,9,53,55,10,52,10,51,44,53,10,44,10,52,49,51,35,49,35,24,47,0,45,22,0,47,22,48,21,22,47,48,54,53,44,7,8,56,7,56,54,37,54,44,37,7,54,43,44,52,43,52,50,6,7,37,36,6,37,5,36,41,5,6,36,4,41,40,4,5,41,3,39,38,3,40,39,3,4,40,2,3,38,42,2,38,1,42,43,1,2,42,0,1,43,0,43,50,0,50,49,0,49,24,10,11,35,10,35,51,24,23,45,24,45,0,57,58,59,57,59,60], + "points": [ + [0,0,0], + [0,0.0875,0], + [0.015194,0.0875,0], + [0.017415326,0.08725025,0], + [0.019525632,0.08651318,0], + [0.021419417,0.085325636,0], + [0.023002,0.083747,0], + [0.03,0.075,0], + [0.0575,0.075,0], + [0.0575,0.055,0], + [0.03,0.055,0], + [0.03,0.003458,0], + [0.029689679,0.0009857035,0], + [0.028777733,-0.0013331121,0], + [0.027320791,-0.0033544651,0], + [0.025409317,-0.0049528438,0], + [0.023162,-0.006029,0], + [0.00904,-0.010737,0], + [0.008006066,-0.011020953,0], + [0.0069476794,-0.01119261,0], + [0.005877,-0.01125,0], + [-0.035,-0.01125,0], + [-0.035,0,0], + [0.002501,-0.008788,0], + [0.002501,0.03,0], + [0.00588,-0.008787,0], + [0.008258,-0.0084,0], + [0.0074808146,-0.008614407,0], + [0.0066850656,-0.008743908,0], + [0.022378,-0.003679,0], + [0.027499,0.003434,0], + [0.02726667,0.001581265,0], + [0.026583847,-0.00015665236,0], + [0.025492856,-0.0016720223,0], + [0.024061328,-0.0028709103,0], + [0.027499,0.03,0], + [0.021062,0.082223,0], + [0.027499,0.074176,0], + [0.015205,0.085038,0], + [0.016871063,0.08485007,0], + [0.018453866,0.08429707,0], + [0.019874465,0.08340657,0], + [0.002501,0.085037,0], + [0.002501,0.057463,0], + [0.027499,0.057463,0], + [0,-0.002463,0], + [0,-0.008788,0], + [-0.032499,-0.002463,0], + [-0.032501,-0.008788,0], + [0.002501,0.0325,0], + [0.002501,0.055,0], + [0.027499,0.0325,0], + [0.027499,0.055,0], + [0.03,0.057463,0], + [0.03,0.072538,0], + [0.054999,0.057463,0], + [0.055001,0.072538,0], + [0.031,0.01625,0], + [0.0575,0.01625,0], + [0.0575,0.00625,0], + [0.031,0.00625,0]] + } + } + }, + { + "path": "a6bc9926-5644-4a87-9ce8-423d445fbe60", + "attributes": { + "customdata": { + "originalStepInstance": "#2163=IfcMember('2cl9acLaHAXvpeGZr4NxvW',$,'Unnamed',$,$,#2615,#2225,$,.BEAM.)" + } + } + }, + { + "path": "a6bc9926-5644-4a87-9ce8-423d445fbe60", + "attributes": { + "bsi::ifc::class": { + "code": "IfcMember", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcMember" + } + } + }, + { + "path": "a6bc9926-5644-4a87-9ce8-423d445fbe60", + "attributes": { + "usd::xformop": { + "transform": [ + [-0.9999999999999886,0,-1.5099580252808492e-07,0], + [0,1,0,0], + [1.5099580252808492e-07,0,-0.9999999999999886,0], + [0.9,0,1.2,1]] + } + } + }, + { + "path": "f016334b-6f9b-4f4f-b4f1-6ca9f40cc786", + "attributes": { + "customdata": { + "originalStepInstance": "#2110=IfcMember('3m5ZDBRvjFJxJnRAdq3CU6',$,'Unnamed',$,$,#2610,#1590,$,.BEAM.)" + } + } + }, + { + "path": "f016334b-6f9b-4f4f-b4f1-6ca9f40cc786", + "attributes": { + "bsi::ifc::class": { + "code": "IfcMember", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcMember" + } + } + }, + { + "path": "f016334b-6f9b-4f4f-b4f1-6ca9f40cc786", + "attributes": { + "usd::xformop": { + "transform": [ + [3.1391647326016295e-07,0,-0.9999999999999508,0], + [0,1,0,0], + [0.9999999999999508,0,3.1391647326016295e-07,0], + [0,0,1.2,1]] + } + } + }, + { + "path": "4842e51d-76f1-59fa-aede-cead4393da7f", + "attributes": { + "usd::usdgeom::mesh": { + "faceVertexIndices": [0,1,2,0,2,3,23,55,21,51,55,23,52,23,24,52,51,23,53,24,25,53,52,24,54,53,25,56,21,55,26,54,25,50,54,26,27,50,26,65,47,68,65,46,47,49,50,27,28,49,27,58,49,28,48,49,58,61,56,48,61,62,56,59,48,58,31,61,48,31,48,59,67,68,22,57,58,28,29,57,28,64,61,31,66,46,65,4,5,63,4,63,64,6,66,67,45,6,7,45,7,11,45,66,6,60,31,59,44,11,10,44,45,11,43,10,9,43,44,10,42,9,8,42,43,9,41,42,8,30,57,29,30,60,57,12,41,8,40,12,20,40,41,12,32,13,4,39,20,19,39,40,20,33,14,13,33,13,32,38,19,18,38,39,19,34,15,14,34,14,33,37,18,17,37,38,18,35,16,15,35,15,34,36,17,16,36,37,17,36,16,35,5,6,67,5,67,22,22,21,56,22,56,62,22,62,63,22,63,5,30,31,60,31,32,64,64,32,4,45,46,66,47,22,68,69,71,72,70,71,69,79,80,105,102,79,105,104,105,80,81,104,80,81,107,104,103,104,107,106,107,81,77,102,103,118,81,82,118,106,81,119,82,83,119,118,82,120,83,84,120,119,83,117,84,85,117,120,84,111,85,86,111,117,85,112,111,86,87,112,86,113,112,87,88,113,87,114,113,88,89,114,88,89,115,114,90,115,89,90,116,115,91,116,90,91,110,116,92,110,91,109,110,92,121,122,108,121,108,109,133,78,132,131,132,123,131,123,124,93,124,121,74,131,124,74,124,93,101,78,133,101,129,128,101,133,129,100,128,127,100,101,128,99,127,126,99,100,127,75,131,74,75,130,131,98,126,125,98,99,126,97,98,125,97,125,130,96,130,75,96,97,130,73,74,93,76,96,75,76,73,94,95,96,76,95,76,94,78,77,122,122,77,108,78,122,123,78,123,132,77,79,102,92,93,109,109,93,121,93,94,73,107,108,77,107,77,103,134,136,137,135,136,134,138,139,140,138,140,141,143,144,145,142,143,145,146,151,155,147,155,154,147,146,155,148,154,153,148,147,154,149,153,152,149,148,153,150,149,152,157,158,159,156,157,159,160,169,175,161,175,174,161,160,175,162,174,173,162,161,174,163,173,172,163,162,173,164,163,172,165,172,171,165,164,172,166,165,171,167,171,170,167,166,171,168,167,170,177,178,179,176,177,179,181,182,183,180,181,183,185,186,187,184,185,187,188,190,191,189,190,188,193,194,195,192,193,195,196,201,205,197,205,204,197,196,205,198,204,203,198,197,204,199,203,202,199,198,203,200,199,202,209,208,207,209,207,206,213,212,211,213,211,210,216,215,214,217,216,214,221,220,218,218,220,219,231,227,222,230,231,223,231,222,223,229,230,224,230,223,224,228,229,225,229,224,225,228,225,226,235,234,233,235,233,232,239,238,236,236,238,237,243,242,241,243,241,240,247,246,245,247,245,244,250,249,248,251,250,248,255,254,252,252,254,253,259,258,257,259,257,256,263,262,261,263,261,260,266,265,264,267,266,264,271,270,269,271,269,268,274,273,272,275,274,272,279,278,276,276,278,277,283,282,281,283,281,280,287,286,284,284,286,285,291,290,289,291,289,288,307,301,292,306,307,293,307,292,293,305,306,294,306,293,294,304,305,295,305,294,295,304,295,296,303,304,297,304,296,297,303,297,298,302,303,299,303,298,299,302,299,300,311,310,309,311,309,308,321,317,312,320,321,313,321,312,313,319,320,314,320,313,314,318,319,315,319,314,315,318,315,316,325,324,323,325,323,322,328,327,326,329,328,326,330,332,333,331,332,330,336,335,334,336,337,335,339,340,341,338,339,341,343,342,344,343,344,345,346,347,348,346,348,349,351,352,353,350,351,353], + "points": [ + [1.3234895e-24,0.0875,3.8140673e-08], + [1.3234892e-24,0,1.650463e-08], + [1.3234891e-23,0,0.9000001], + [1.3234891e-23,0.0875,0.90000015], + [0.027499,0.03,0.027499033], + [0.002501,0.03,0.0025010246], + [0.002501,-0.008788,0.002501015], + [0.00588,-0.008787,0.0058800164], + [0.008258,-0.0084,0.008258017], + [0.0076772086,-0.008568684,0.007677226], + [0.0070846863,-0.008689888,0.007084703], + [0.0064843083,-0.008762819,0.0064843246], + [0.022378,-0.003679,0.022378022], + [0.027499,0.003434,0.027499026], + [0.02739287,0.0021762955,0.027392896], + [0.027077328,0.00095419964,0.027077354], + [0.026561312,-0.00019767368,0.026561338], + [0.025859438,-0.0012466997,0.025859462], + [0.024991583,-0.0021631666,0.024991607], + [0.023982327,-0.0029211172,0.023982352], + [0.023202656,-0.003347671,0.023202678], + [1.3234895e-24,0.0875,3.8140673e-08], + [1.3234892e-24,0,1.650463e-08], + [0.015194,0.0875,0.015194043], + [0.018136473,0.08705737,0.018136518], + [0.020818334,0.085768305,0.020818379], + [0.021985792,0.08483935,0.021985836], + [0.023002,0.083747,0.023002045], + [0.03,0.075,0.030000044], + [0.0575,0.075,0.057500057], + [0.0575,0.055,0.05750005], + [0.03,0.055,0.03000004], + [0.03,0.003458,0.030000027], + [0.029858235,0.0017796973,0.029858263], + [0.029436797,0.00014899582,0.029436825], + [0.028747642,-0.001387839,0.028747668], + [0.02781032,-0.0027872052,0.027810344], + [0.026651425,-0.0040094005,0.026651451], + [0.025303839,-0.00501975,0.025303863], + [0.024262898,-0.005587993,0.02426292], + [0.023162,-0.006029,0.023162022], + [0.00904,-0.010737,0.009040017], + [0.008267311,-0.010960386,0.008267328], + [0.007479174,-0.011120972,0.0074791904], + [0.006680683,-0.011217718,0.0066806986], + [0.005877,-0.01125,0.0058770156], + [-0.035,-0.01125,-0.034999996], + [-0.035,0,-0.034999996], + [0.027499,0.057463,0.027499039], + [0.027499,0.074176,0.027499044], + [0.021062,0.082223,0.021062044], + [0.015205,0.085038,0.015205042], + [0.017411938,0.0847053,0.01741198], + [0.019423535,0.08373848,0.01942358], + [0.020299401,0.08304197,0.020299444], + [0.002501,0.085037,0.0025010384], + [0.002501,0.057463,0.0025010316], + [0.055001,0.072538,0.055001054], + [0.03,0.072538,0.030000044], + [0.03,0.057463,0.03000004], + [0.054999,0.057463,0.05499905], + [0.027499,0.055,0.027499039], + [0.002501,0.055,0.002501031], + [0.002501,0.0325,0.0025010253], + [0.027499,0.0325,0.027499033], + [-0.032501,-0.008788,-0.032500997], + [1.3234892e-24,-0.008788,1.4331631e-08], + [1.3234892e-24,-0.002463,1.5895607e-08], + [-0.032499,-0.002463,-0.032498997], + [0.015194,0.0875,0.015194043], + [1.3234895e-24,0.0875,3.8140673e-08], + [1.3234891e-23,0.0875,0.90000015], + [0.015194,0.0875,0.88480616], + [0.054999,0.057463,0.84500116], + [0.03,0.057463,0.8700001], + [0.03,0.072538,0.8700001], + [0.055001,0.072538,0.84499913], + [1.3234891e-23,0,0.9000001], + [1.3234891e-23,0.0875,0.90000015], + [-0.035,0,0.9350001], + [-0.035,-0.01125,0.93500006], + [0.005877,-0.01125,0.8941231], + [0.006680683,-0.011217718,0.8933194], + [0.007479174,-0.011120972,0.8925209], + [0.008267311,-0.010960386,0.89173275], + [0.00904,-0.010737,0.8909601], + [0.023162,-0.006029,0.8768381], + [0.025853055,-0.0046503283,0.87414706], + [0.027650518,-0.0029819738,0.87234956], + [0.028906511,-0.0010892329,0.8710936], + [0.029589213,0.00062086154,0.87041086], + [0.029896807,0.0020246333,0.8701033], + [0.03,0.003458,0.8700001], + [0.03,0.055,0.8700001], + [0.0575,0.055,0.84250015], + [0.0575,0.075,0.84250015], + [0.03,0.075,0.8700002], + [0.023002,0.083747,0.8769982], + [0.021062722,0.085596636,0.8789374], + [0.018701771,0.08686465,0.88129836], + [0.016976433,0.08733994,0.88302374], + [0.015194,0.0875,0.88480616], + [-0.032499,-0.002463,0.9324991], + [1.3234891e-23,-0.002463,0.9000001], + [1.3234891e-23,-0.008788,0.9000001], + [-0.032501,-0.008788,0.9325011], + [0.00588,-0.008787,0.8941201], + [0.002501,-0.008788,0.8974991], + [0.002501,0.03,0.89749914], + [0.027499,0.03,0.87250113], + [0.027499,0.003434,0.8725011], + [0.022378,-0.003679,0.8776221], + [0.024393667,-0.0026439307,0.8756064], + [0.025739772,-0.0013927278,0.8742603], + [0.026680272,2.6147964e-05,0.8733198], + [0.027191449,0.0013078401,0.87280864], + [0.027421748,0.0023598508,0.8725784], + [0.008258,-0.0084,0.8917421], + [0.0064843083,-0.008762819,0.89351577], + [0.0070846863,-0.008689888,0.8929154], + [0.0076772086,-0.008568684,0.8923229], + [0.027499,0.0325,0.87250113], + [0.002501,0.0325,0.89749914], + [0.002501,0.055,0.89749914], + [0.027499,0.055,0.87250113], + [0.021062,0.082223,0.87893814], + [0.01960687,0.08360976,0.88039327], + [0.017835928,0.08456071,0.88216424], + [0.016541885,0.084917426,0.88345826], + [0.015205,0.085038,0.8847952], + [0.027499,0.074176,0.87250113], + [0.027499,0.057463,0.87250113], + [0.002501,0.057463,0.89749914], + [0.002501,0.085037,0.89749914], + [1.3234892e-24,0,1.650463e-08], + [-0.035,0,-0.034999996], + [-0.035,0,0.9350001], + [1.3234891e-23,0,0.9000001], + [-0.035,0,-0.034999996], + [-0.035,-0.01125,-0.034999996], + [-0.035,-0.01125,0.93500006], + [-0.035,0,0.9350001], + [-0.035,-0.01125,-0.034999996], + [0.005877,-0.01125,0.0058770156], + [0.005877,-0.01125,0.8941231], + [-0.035,-0.01125,0.93500006], + [0.00904,-0.010737,0.009040017], + [0.008267311,-0.010960386,0.008267328], + [0.007479174,-0.011120972,0.0074791904], + [0.006680683,-0.011217718,0.0066806986], + [0.005877,-0.01125,0.0058770156], + [0.00904,-0.010737,0.8909601], + [0.005877,-0.01125,0.8941231], + [0.006680683,-0.011217718,0.8933194], + [0.007479174,-0.011120972,0.8925209], + [0.008267311,-0.010960386,0.89173275], + [0.00904,-0.010737,0.009040017], + [0.023162,-0.006029,0.023162022], + [0.023162,-0.006029,0.8768381], + [0.00904,-0.010737,0.8909601], + [0.03,0.003458,0.030000027], + [0.029858235,0.0017796973,0.029858263], + [0.029436797,0.00014899582,0.029436825], + [0.028747642,-0.001387839,0.028747668], + [0.02781032,-0.0027872052,0.027810344], + [0.026651425,-0.0040094005,0.026651451], + [0.025303839,-0.00501975,0.025303863], + [0.024262898,-0.005587993,0.02426292], + [0.023162,-0.006029,0.023162022], + [0.03,0.003458,0.8700001], + [0.023162,-0.006029,0.8768381], + [0.025853055,-0.0046503283,0.87414706], + [0.027650518,-0.0029819738,0.87234956], + [0.028906511,-0.0010892329,0.8710936], + [0.029589213,0.00062086154,0.87041086], + [0.029896807,0.0020246333,0.8701033], + [0.03,0.003458,0.030000027], + [0.03,0.055,0.03000004], + [0.03,0.055,0.8700001], + [0.03,0.003458,0.8700001], + [0.03,0.055,0.03000004], + [0.0575,0.055,0.05750005], + [0.0575,0.055,0.84250015], + [0.03,0.055,0.8700001], + [0.0575,0.055,0.05750005], + [0.0575,0.075,0.057500057], + [0.0575,0.075,0.84250015], + [0.0575,0.055,0.84250015], + [0.0575,0.075,0.057500057], + [0.03,0.075,0.030000044], + [0.03,0.075,0.8700002], + [0.0575,0.075,0.84250015], + [0.03,0.075,0.030000044], + [0.023002,0.083747,0.023002045], + [0.023002,0.083747,0.8769982], + [0.03,0.075,0.8700002], + [0.015194,0.0875,0.015194043], + [0.018136473,0.08705737,0.018136518], + [0.020818334,0.085768305,0.020818379], + [0.021985792,0.08483935,0.021985836], + [0.023002,0.083747,0.023002045], + [0.015194,0.0875,0.88480616], + [0.023002,0.083747,0.8769982], + [0.021062722,0.085596636,0.8789374], + [0.018701771,0.08686465,0.88129836], + [0.016976433,0.08733994,0.88302374], + [0.027499,0.057463,0.027499039], + [0.027499,0.074176,0.027499044], + [0.027499,0.074176,0.87250113], + [0.027499,0.057463,0.87250113], + [0.002501,0.057463,0.0025010316], + [0.027499,0.057463,0.027499039], + [0.027499,0.057463,0.87250113], + [0.002501,0.057463,0.89749914], + [0.002501,0.085037,0.0025010384], + [0.002501,0.057463,0.0025010316], + [0.002501,0.057463,0.89749914], + [0.002501,0.085037,0.89749914], + [0.015205,0.085038,0.015205042], + [0.002501,0.085037,0.0025010384], + [0.002501,0.085037,0.89749914], + [0.015205,0.085038,0.8847952], + [0.015205,0.085038,0.015205042], + [0.017411938,0.0847053,0.01741198], + [0.019423535,0.08373848,0.01942358], + [0.020299401,0.08304197,0.020299444], + [0.021062,0.082223,0.021062044], + [0.015205,0.085038,0.8847952], + [0.021062,0.082223,0.87893814], + [0.01960687,0.08360976,0.88039327], + [0.017835928,0.08456071,0.88216424], + [0.016541885,0.084917426,0.88345826], + [0.027499,0.074176,0.027499044], + [0.021062,0.082223,0.021062044], + [0.021062,0.082223,0.87893814], + [0.027499,0.074176,0.87250113], + [0.055001,0.072538,0.055001054], + [0.03,0.072538,0.030000044], + [0.03,0.072538,0.8700001], + [0.055001,0.072538,0.84499913], + [0.054999,0.057463,0.05499905], + [0.055001,0.072538,0.055001054], + [0.055001,0.072538,0.84499913], + [0.054999,0.057463,0.84500116], + [0.03,0.057463,0.03000004], + [0.054999,0.057463,0.05499905], + [0.054999,0.057463,0.84500116], + [0.03,0.057463,0.8700001], + [0.03,0.072538,0.030000044], + [0.03,0.057463,0.03000004], + [0.03,0.057463,0.8700001], + [0.03,0.072538,0.8700001], + [0.027499,0.055,0.027499039], + [0.002501,0.055,0.002501031], + [0.002501,0.055,0.89749914], + [0.027499,0.055,0.87250113], + [0.027499,0.0325,0.027499033], + [0.027499,0.055,0.027499039], + [0.027499,0.055,0.87250113], + [0.027499,0.0325,0.87250113], + [0.002501,0.0325,0.0025010253], + [0.027499,0.0325,0.027499033], + [0.027499,0.0325,0.87250113], + [0.002501,0.0325,0.89749914], + [0.002501,0.055,0.002501031], + [0.002501,0.0325,0.0025010253], + [0.002501,0.0325,0.89749914], + [0.002501,0.055,0.89749914], + [-0.032501,-0.008788,-0.032500997], + [1.3234892e-24,-0.008788,1.4331631e-08], + [1.3234891e-23,-0.008788,0.9000001], + [-0.032501,-0.008788,0.9325011], + [-0.032499,-0.002463,-0.032498997], + [-0.032501,-0.008788,-0.032500997], + [-0.032501,-0.008788,0.9325011], + [-0.032499,-0.002463,0.9324991], + [1.3234892e-24,-0.002463,1.5895607e-08], + [-0.032499,-0.002463,-0.032498997], + [-0.032499,-0.002463,0.9324991], + [1.3234891e-23,-0.002463,0.9000001], + [1.3234892e-24,-0.008788,1.4331631e-08], + [1.3234892e-24,-0.002463,1.5895607e-08], + [1.3234891e-23,-0.002463,0.9000001], + [1.3234891e-23,-0.008788,0.9000001], + [0.027499,0.03,0.027499033], + [0.002501,0.03,0.0025010246], + [0.002501,0.03,0.89749914], + [0.027499,0.03,0.87250113], + [0.027499,0.003434,0.027499026], + [0.027499,0.03,0.027499033], + [0.027499,0.03,0.87250113], + [0.027499,0.003434,0.8725011], + [0.027499,0.003434,0.027499026], + [0.02739287,0.0021762955,0.027392896], + [0.027077328,0.00095419964,0.027077354], + [0.026561312,-0.00019767368,0.026561338], + [0.025859438,-0.0012466997,0.025859462], + [0.024991583,-0.0021631666,0.024991607], + [0.023982327,-0.0029211172,0.023982352], + [0.023202656,-0.003347671,0.023202678], + [0.022378,-0.003679,0.022378022], + [0.027499,0.003434,0.8725011], + [0.022378,-0.003679,0.8776221], + [0.024393667,-0.0026439307,0.8756064], + [0.025739772,-0.0013927278,0.8742603], + [0.026680272,2.6147964e-05,0.8733198], + [0.027191449,0.0013078401,0.87280864], + [0.027421748,0.0023598508,0.8725784], + [0.008258,-0.0084,0.008258017], + [0.022378,-0.003679,0.022378022], + [0.022378,-0.003679,0.8776221], + [0.008258,-0.0084,0.8917421], + [0.008258,-0.0084,0.008258017], + [0.0076772086,-0.008568684,0.007677226], + [0.0070846863,-0.008689888,0.007084703], + [0.0064843083,-0.008762819,0.0064843246], + [0.00588,-0.008787,0.0058800164], + [0.008258,-0.0084,0.8917421], + [0.00588,-0.008787,0.8941201], + [0.0064843083,-0.008762819,0.89351577], + [0.0070846863,-0.008689888,0.8929154], + [0.0076772086,-0.008568684,0.8923229], + [0.002501,-0.008788,0.002501015], + [0.00588,-0.008787,0.0058800164], + [0.00588,-0.008787,0.8941201], + [0.002501,-0.008788,0.8974991], + [0.002501,0.03,0.0025010246], + [0.002501,-0.008788,0.002501015], + [0.002501,-0.008788,0.8974991], + [0.002501,0.03,0.89749914], + [0.0575,0.01625,0.057500042], + [0.031,0.01625,0.031000031], + [0.031,0.01625,0.86900014], + [0.0575,0.01625,0.8425001], + [0.0575,0.01625,0.057500042], + [0.031,0.01625,0.031000031], + [0.0575,0.00625,0.05750004], + [0.031,0.00625,0.031000027], + [0.0575,0.00625,0.05750004], + [0.0575,0.01625,0.057500042], + [0.0575,0.01625,0.8425001], + [0.0575,0.00625,0.8425001], + [0.031,0.01625,0.86900014], + [0.0575,0.01625,0.8425001], + [0.031,0.00625,0.8690001], + [0.0575,0.00625,0.8425001], + [0.031,0.01625,0.031000031], + [0.031,0.00625,0.031000027], + [0.031,0.00625,0.8690001], + [0.031,0.01625,0.86900014], + [0.031,0.00625,0.031000027], + [0.0575,0.00625,0.05750004], + [0.0575,0.00625,0.8425001], + [0.031,0.00625,0.8690001]] + } + } + }, + { + "path": "319a33df-2615-41bd-a319-925d327baf43", + "attributes": { + "customdata": { + "originalStepInstance": "#2436=IfcPlate('0ncZFV9XL1lQCPabqoUwz3',$,'Unnamed',$,$,#2625,#2447,$,.SHEET.)" + } + } + }, + { + "path": "319a33df-2615-41bd-a319-925d327baf43", + "attributes": { + "bsi::ifc::class": { + "code": "IfcPlate", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcPlate" + } + } + }, + { + "path": "319a33df-2615-41bd-a319-925d327baf43", + "attributes": { + "usd::xformop": { + "transform": [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0.027498865127560057,0.0162499994039536,0.0300252437591599,1]] + } + } + }, + { + "path": "e6d106c8-87b8-5cf1-9ce4-1a6401d9ba34", + "attributes": { + "usd::usdgeom::mesh": { + "faceVertexIndices": [3,0,1,3,1,2,7,4,5,7,5,6,11,8,9,11,9,10,15,12,13,15,13,14,16,17,18,16,18,19,22,21,20,23,22,20], + "points": [ + [0,0.038749993,0], + [0,0.038749993,1.14], + [0.8425009,0.038749993,1.14], + [0.8425009,0.038749993,0], + [0.8425009,0.038749993,0], + [0.8425009,0.038749993,1.14], + [0.8425009,0,1.14], + [0.8425009,0,0], + [0.8425009,0,0], + [0.8425009,0,1.14], + [0,0,1.14], + [0,0,0], + [0,0,0], + [0,0,1.14], + [0,0.038749993,1.14], + [0,0.038749993,0], + [0,0.038749993,0], + [0.8425009,0.038749993,0], + [0.8425009,0,0], + [0,0,0], + [0,0.038749993,1.14], + [0.8425009,0.038749993,1.14], + [0.8425009,0,1.14], + [0,0,1.14]] + } + } + }, + { + "path": "e0d81185-3f80-4b48-9afe-2a029aac336b", + "attributes": { + "customdata": { + "originalStepInstance": "#1591=IfcMember('3Ws165Fu1BI9h_AWAQh3Dh',$,'Unnamed',$,$,#2605,#1590,$,.BEAM.)" + } + } + }, + { + "path": "e0d81185-3f80-4b48-9afe-2a029aac336b", + "attributes": { + "bsi::ifc::class": { + "code": "IfcMember", + "uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcMember" + } + } + }, + { + "path": "08f06095-3f32-55b9-a353-61c9aca5cc4d", + "attributes": { + "usd::usdgeom::visibility": { + "visibility": "invisible" + } + } + }, + { + "path": "5ad6f475-c04c-5628-8b9d-75d0bab0c0e5", + "attributes": { + "usd::usdgeom::visibility": { + "visibility": "invisible" + } + } + }, + { + "path": "bc887b0b-aa5a-4f03-a02e-bcffc4771146", + "attributes": { + "gltf::material": { + "pbrMetallicRoughness": { + "baseColorFactor": [0.6, 0.55, 0.5, 1.0], + "metallicFactor": 0.0, + "roughnessFactor": 0.5 + } + } + } + }, + { + "path": "f8dc129a-d241-41bd-b45e-c979fe2cd601", + "attributes": { + "gltf::material": { + "pbrMetallicRoughness": { + "baseColorFactor": [0.6, 0.8, 0.7, 0.2], + "metallicFactor": 0.0, + "roughnessFactor": 0.0 + } + } + } + }, + { + "path": "e0d81185-3f80-4b48-9afe-2a029aac336b", + "attributes": { + "usd::xformop": { + "transform": [ + [7.549790126404311e-08,0,0.9999999999999972,0], + [0,1,0,0], + [-0.9999999999999972,0,7.549790126404311e-08,0], + [0.9,0,0,1]] + } + } + }], + "imports": [ + { + "uri": "https://ifcx.dev/@standards.buildingsmart.org/ifc/core/ifc@v5a.ifcx" + }, + { + "uri": "https://ifcx.dev/@standards.buildingsmart.org/ifc/core/ifc@v5a.ifcx" + }, + { + "uri": "https://ifcx.dev/@standards.buildingsmart.org/ifc/core/ifc@v5a.ifcx" + }, + { + "uri": "https://ifcx.dev/@openusd.org/usd@v1.ifcx" + }, + { + "uri": "https://ifcx.dev/@openusd.org/usd@v1.ifcx" + }, + { + "uri": "https://ifcx.dev/@standards.buildingsmart.org/ifc/core/ifc@v5a.ifcx" + }] +} diff --git a/schema/ifcx.tsp b/schema/ifcx.tsp index d0f3157..25b334c 100644 --- a/schema/ifcx.tsp +++ b/schema/ifcx.tsp @@ -37,7 +37,8 @@ enum DataType Array: "Array", Object: "Object", Reference: "Reference", - Blob: "Blob" + Blob: "Blob", + Union: "Union" } model EnumRestrictions @@ -58,9 +59,14 @@ model ObjectRestrictions values: Record; } +model UnionRestrictions +{ + values: IfcxValueDescription[]; +} + model IfcxValueDescription { - dataType: DataType; + dataType?: DataType; optional?: boolean; inherits?: string[]; quantityKind?: QuantityKind; @@ -68,6 +74,8 @@ model IfcxValueDescription enumRestrictions?: EnumRestrictions; arrayRestrictions?: ArrayRestrictions; objectRestrictions?: ObjectRestrictions; + unionRestrictions?: UnionRestrictions; + ref?: string; } model IfcxSchema diff --git a/schema/out/@typespec/openapi3/openapi.yaml b/schema/out/@typespec/openapi3/openapi.yaml index 310cbee..b095800 100644 --- a/schema/out/@typespec/openapi3/openapi.yaml +++ b/schema/out/@typespec/openapi3/openapi.yaml @@ -30,6 +30,7 @@ components: - Object - Reference - Blob + - Union EnumRestrictions: type: object required: @@ -65,13 +66,16 @@ components: type: object required: - id - - version + - ifcxVersion + - dataVersion - author - timestamp properties: id: type: string - version: + ifcxVersion: + type: string + dataVersion: type: string author: type: string @@ -108,8 +112,6 @@ components: $ref: '#/components/schemas/IfcxValueDescription' IfcxValueDescription: type: object - required: - - dataType properties: dataType: $ref: '#/components/schemas/DataType' @@ -127,6 +129,10 @@ components: $ref: '#/components/schemas/ArrayRestrictions' objectRestrictions: $ref: '#/components/schemas/ObjectRestrictions' + unionRestrictions: + $ref: '#/components/schemas/UnionRestrictions' + ref: + type: string ImportNode: type: object required: @@ -162,6 +168,15 @@ components: - Energy - Power - Volume + UnionRestrictions: + type: object + required: + - values + properties: + values: + type: array + items: + $ref: '#/components/schemas/IfcxValueDescription' code: type: string pattern: diff --git a/schema/out/ts/ifcx.d.ts b/schema/out/ts/ifcx.d.ts index 745fa2b..ea0635e 100644 --- a/schema/out/ts/ifcx.d.ts +++ b/schema/out/ts/ifcx.d.ts @@ -13,7 +13,7 @@ export interface components { value: components["schemas"]["IfcxValueDescription"]; }; /** @enum {string} */ - DataType: "Real" | "Boolean" | "Integer" | "String" | "DateTime" | "Enum" | "Array" | "Object" | "Reference" | "Blob"; + DataType: "Real" | "Boolean" | "Integer" | "String" | "DateTime" | "Enum" | "Array" | "Object" | "Reference" | "Blob" | "Union"; EnumRestrictions: { options: string[]; }; @@ -27,7 +27,8 @@ export interface components { }; IfcxHeader: { id: string; - version: string; + ifcxVersion: string; + dataVersion: string; author: string; timestamp: string; }; @@ -48,13 +49,15 @@ export interface components { value: components["schemas"]["IfcxValueDescription"]; }; IfcxValueDescription: { - dataType: components["schemas"]["DataType"]; + dataType?: components["schemas"]["DataType"]; optional?: boolean; inherits?: string[]; quantityKind?: components["schemas"]["QuantityKind"]; enumRestrictions?: components["schemas"]["EnumRestrictions"]; arrayRestrictions?: components["schemas"]["ArrayRestrictions"]; objectRestrictions?: components["schemas"]["ObjectRestrictions"]; + unionRestrictions?: components["schemas"]["UnionRestrictions"]; + ref?: string; }; ImportNode: { uri: string; @@ -67,6 +70,9 @@ export interface components { }; /** @enum {string} */ QuantityKind: "Plane angle" | "Thermodynamic temperature" | "Electric current" | "Time" | "Frequency" | "Mass" | "Length" | "Linear velocity" | "Force" | "Pressure" | "Area" | "Energy" | "Power" | "Volume"; + UnionRestrictions: { + values: components["schemas"]["IfcxValueDescription"][]; + }; code: string; path: string; }; diff --git a/src/ifcx-core/schema/schema-validation.ts b/src/ifcx-core/schema/schema-validation.ts index 89cd19e..17f0cc3 100644 --- a/src/ifcx-core/schema/schema-validation.ts +++ b/src/ifcx-core/schema/schema-validation.ts @@ -6,6 +6,44 @@ export class SchemaValidationError extends Error } +function TryValidateAttributeValue(desc: IfcxValueDescription, value: any, path: string, schemas: {[key: string]: IfcxSchema}) +{ + try { + ValidateAttributeValue(desc, value, path, schemas); + return null; + } catch (e) { + return e; + } +} + +function stringifyWithDepthLimit(value, maxDepth=3) { + const seen = new WeakSet(); + + function traverse(val, depth) { + if (depth > maxDepth) { + return Array.isArray(val) ? [] : (typeof val === "object" && val !== null ? {} : val); + } + + if (val && typeof val === "object") { + if (seen.has(val)) return; // prevent cycles + seen.add(val); + + if (Array.isArray(val)) { + return val.map(v => traverse(v, depth + 1)); + } else { + const out = {}; + for (const [k, v] of Object.entries(val)) { + out[k] = traverse(v, depth + 1); + } + return out; + } + } + return val; + } + + return JSON.stringify(traverse(value, 1)); + } + function ValidateAttributeValue(desc: IfcxValueDescription, value: any, path: string, schemas: {[key: string]: IfcxSchema}) { if (desc.optional && value === undefined) @@ -26,6 +64,21 @@ function ValidateAttributeValue(desc: IfcxValueDescription, value: any, path: st }); } + while (desc.ref) { + const oldRef = desc.ref; + console.log(oldRef, ...Object.keys(value)); + if (typeof value === "object" && Object.keys(value).length == 1 && Object.keys(value)[0] === oldRef) { + // @todo this is a nasty hack out of utter laziness and uncertainty whether to use a + // *tagged* union or not, but for now, when (union) refs are observed and similar keys + // are found in the *data*, then the data is traversed accordingly. + value = Object.values(value)[0]; + } + desc = schemas[desc.ref].value; + if (!desc) { + throw new SchemaValidationError(`Reference to undefined schema type ${oldRef}`); + } + } + if (desc.dataType === "Boolean") { if (typeof value !== "boolean") @@ -95,7 +148,7 @@ function ValidateAttributeValue(desc: IfcxValueDescription, value: any, path: st if (!hasOwn) { - throw new SchemaValidationError(`Expected "${value}" to have key ${key}`); + throw new SchemaValidationError(`Expected "${typeof value === 'object' ? JSON.stringify(value) : value}" to have key ${key}`); } ValidateAttributeValue(desc.objectRestrictions!.values[key], value[key], path + "." + key, schemas); }) @@ -111,6 +164,14 @@ function ValidateAttributeValue(desc: IfcxValueDescription, value: any, path: st ValidateAttributeValue(desc.arrayRestrictions!.value, entry, path + "..", schemas); }) } + else if (desc.dataType === "Union") + { + const nonFailures = desc.unionRestrictions ? desc.unionRestrictions.values.map(v => TryValidateAttributeValue(v, value, path + "..", schemas)).filter(v => v === null) : []; + console.log("Union", stringifyWithDepthLimit(value), ...(desc.unionRestrictions ? desc.unionRestrictions.values.map(a => stringifyWithDepthLimit(a)) : []), nonFailures.length) + if (nonFailures.length == 0) { + throw new SchemaValidationError(`Expected "${stringifyWithDepthLimit(value)}" to be match any of the types ${stringifyWithDepthLimit(desc.unionRestrictions?.values)}`); + } + } else { throw new SchemaValidationError(`Unexpected datatype ${desc.dataType}`); diff --git a/src/utils/python/externalise_schema.py b/src/utils/python/externalise_schema.py index 0c27b4c..f69ac88 100644 --- a/src/utils/python/externalise_schema.py +++ b/src/utils/python/externalise_schema.py @@ -7,6 +7,7 @@ obj["imports"] = [] prefix = 'https://ifcx.dev' +local_path = '../../../../ifcx.dev/' mapping = { 'bsi::ifc::prop': '@standards.buildingsmart.org/ifc/core/prop@v5a.ifcx', @@ -37,7 +38,7 @@ def w(path, name, schema): for k, v in list(obj["schemas"].items()): for m, n in mapping.items(): if k.startswith(m): - w('../../../web/' + n, k, v) + w(local_path + n, k, v) del obj["schemas"][k] if m not in (x['uri'] for x in obj["imports"]): obj["imports"].append({ diff --git a/src/utils/python/ifc4-to-usda.py b/src/utils/python/ifc4-to-usda.py index 65d1b90..4d5d420 100644 --- a/src/utils/python/ifc4-to-usda.py +++ b/src/utils/python/ifc4-to-usda.py @@ -139,6 +139,9 @@ def get_name(el): if el in name_mapping: return name_mapping[el] n = el.Name or f'Unnamed {el.is_a()[3:]}' + + if n[0].isdigit(): + n = "N" + n postfix = 0 while True: @@ -398,6 +401,175 @@ def process(el, path=(), parentPath=None, asclass=False): basisdef = UsdGeom.Mesh.Define(stage, xf.GetPath().pathString + "/Basis") basisdef.GetPrim().GetInherits().AddInherit(basisclass.GetPath()) + if r.Items[0].is_a('IfcBooleanClippingResult') and os.path.basename(fn) == 'window-frame.ifc': + def is_rectangle(pts, tol=1e-8): + if pts.shape != (4, pts.shape[1]): + return False + for i in range(4): + p0 = pts[i] + p1 = pts[(i-1) % 4] + p2 = pts[(i+1) % 4] + v1 = p1 - p0 + v2 = p2 - p0 + if not np.isclose(np.dot(v1, v2), 0.0, atol=tol): + return False + cent = np.average([pts.min(axis=0), pts.max(axis=0)], axis=0) + width, height = (pts.max(axis=0) - pts.min(axis=0))[0:2].tolist() + return cent, (width, height) + def is_linear(e): + if e.basis is None: + return True + elif e.basis.kind() == ifcopenshell.ifcopenshell_wrapper.LINE: + return True + else: + return False + def group_consecutive_linear(edges): + groups = [] + current_group = [] + + for lin, edge in zip(map(is_linear, edges), edges): + if lin: + current_group.append(edge) + else: + if current_group: + groups.append(current_group) + current_group = [] + groups.append(edge) + if current_group: + groups.append(current_group) + return groups + def format_polyline(edges): + if is_loop := isinstance(edges, ifcopenshell.ifcopenshell_wrapper.loop): + edges = edges.children + points = [p.start.components[0:2] for p in edges] + # if not is_loop: + points += [edges[-1].end.components[0:2]] + return {"ifc5:geometry:procedural:polyline": { + "Points": points + }} + def format_circular_arc(edge): + ccw = True + if edge.curve_sense is False: + # ? + ccw = False + start = np.array(edge.start.components[0:2]) + end = np.array(edge.end.components[0:2]) + center = np.array([r[3] for r in edge.basis.matrix.components[0:2]]) + r = edge.basis.radius + theta1 = np.arctan2(start[1] - center[1], start[0] - center[0]) + theta2 = np.arctan2(end[1] - center[1], end[0] - center[0]) + theta1 = theta1 % (2*np.pi) + theta2 = theta2 % (2*np.pi) + if ccw: + if theta2 < theta1: + theta2 += 2*np.pi + else: + if theta2 > theta1: + theta2 -= 2*np.pi + mid_theta = (theta1 + theta2) / 2.0 + midpoint = center + r * np.array([np.cos(mid_theta), np.sin(mid_theta)]) + return {"ifc5:geometry:procedural:circular_arc": { + "Points": np.concatenate((start[np.newaxis,:], midpoint[np.newaxis,:], end[np.newaxis,:])).tolist() + }} + + itm = r.Items[0] + + halfspaces = [itm.FirstOperand.SecondOperand, itm.SecondOperand] + extrusion = itm.FirstOperand.FirstOperand + I = ifcopenshell.ifcopenshell_wrapper.map_shape(ifcopenshell.geom.settings(), extrusion.wrapped_data) + depth = I.children[0].depth + drc = I.children[0].direction.components + face1, face2 = sorted((ext.basis for ext in I.children), key=lambda ch:len(ch.children)) + ps1 = np.array([p.start.components for p in face1.children[0].children]) + assert is_rectangle(ps1) + cent, (width, height) = is_rectangle(ps1) + + # first profile is just a rectangle + profiles = [{"ifc5:geometry:procedural:rectangle": { + "Position": { + "Location": cent[0:2].tolist() + }, + "Width": width, + "Height": height + }}] + + # second profile is with voids + exterior = None + interior = [] + + for lp in face2.children: + + if all(map(is_linear, lp.children)): + ps2 = np.array([p.start.components[0:2] for p in lp.children]) + if cwh := is_rectangle(ps2): + cent, (width, height) = cwh + profile = {"ifc5:geometry:procedural:rectangle": { + "Position": { + "Location": cent[0:2].tolist() + }, + "Width": width, + "Height": height + }} + else: + # breakpoint() + profile = format_polyline(lp) + else: + # breakpoint() + groups = group_consecutive_linear(lp) + segments = [] + for grp in groups: + if isinstance(grp, list): + segments.append(format_polyline(grp)) + else: + segments.append(format_circular_arc(grp)) + profile = {"ifc5:geometry:procedural:composite_curve": { + "Segments": segments, + }} + + if lp.external: + exterior = profile + else: + interior.append(profile) + + profiles.append( + {"ifc5:geometry:procedural:profile_with_voids": { + "Exterior": exterior, + "Interior": interior + }} + ) + + comp = {"ifc5:geometry:procedural:composite_profile": { + "Profiles": profiles + }} + + verts, edges, faces = [], [], [] + + for fa in r.Items[0][1][1][0][2]: + geom = ifcopenshell.geom.create_shape(ifcopenshell.geom.settings(), fa) + num_verts = sum(map(len, verts)) + edges.append(np.array(geom.edges).reshape((-1, 2)) + num_verts) + faces.append(np.array(geom.faces).reshape((-1, 3)) + num_verts) + verts.append(np.array(geom.verts).reshape((-1, 3))) + + for arr in (verts, edges, faces): + arr[:] = [np.concatenate(arr)] + + + UsdGeom.Mesh.Define(stage, "/Profiles").GetPrim().GetInherits().AddInherit("/ProfilesClass") + profiledefclass = stage.CreateClassPrim("/WindowFrameProfile") + profiledefclass.SetTypeName("Mesh") + profiledef = UsdGeom.Mesh(profiledefclass) + UsdGeom.Mesh.Define(stage, "/ProfilesClass/WindowFrameProfile").GetPrim().GetInherits().AddInherit("/WindowFrameProfile") + + write_geom_2(profiledef, "Body", verts[0], faces[0], edges[0]) + profiledef.GetPrim().CreateAttribute(f'ifc5:procedural_geometry:has_profile', Sdf.ValueTypeNames.String).Set( + json.dumps(comp) + ) + + basisdef = UsdGeom.Mesh.Define(stage, xf.GetPath().pathString + "/Basis") + basisdef.GetPrim().GetInherits().AddInherit(profiledef.GetPath()) + + if el.is_a('IfcAlignmentSegment'): args = el.DesignParameters.get_info(recursive=True, include_identifier=False) args.pop('type') @@ -432,21 +604,24 @@ def process(el, path=(), parentPath=None, asclass=False): return xf or xf2 -for typeobj in [t for t in f.by_type('IfcTypeObject') if t.Types and len(t.Types[0].RelatedObjects) > 1]: +first_or_none = lambda agg: agg[0] if agg else None +get_occurence_of_type = lambda tobj: first_or_none(getattr(tobj, 'ObjectTypeOf', ()) + getattr(tobj, 'Types', ())) + +for typeobj in []: # [t for t in f.by_type('IfcTypeObject') if get_occurence_of_type(t) and len(get_occurence_of_type(t).RelatedObjects) > 1]: if os.path.basename(fn) == 'domestic-hot-water.ifc' and typeobj.is_a('IfcWallType'): continue xf = process(typeobj, ('TypeLibrary',), asclass=True) - for occ in typeobj.Types[0].RelatedObjects: + for occ in get_occurence_of_type(typeobj).RelatedObjects: types[occ].append(xf.GetPath()) - occ = typeobj.Types[0].RelatedObjects[0] + occ = get_occurence_of_type(typeobj).RelatedObjects[0] if occ.FillsVoids: write_geom(occ.FillsVoids[0].RelatingOpeningElement, xf, override='Void', istype=True) write_geom(occ, xf, istype=True) DIRECT_PROPS = True -for typeobj in f.by_type('IfcPropertySet'): +for typeobj in []: # f.by_type('IfcPropertySet'): if typeobj.Name.startswith('EPset_'): continue if DIRECT_PROPS: continue @@ -500,18 +675,18 @@ def process(el, path=(), parentPath=None, asclass=False): created_nodes[a].GetPrim().CreateRelationship(f'ifc5:system:connectsTo').AddTarget(created_nodes[b].GetPath().pathString) -for typeobj in f.by_type('IfcPropertySet'): +for typeobj in []: # f.by_type('IfcPropertySet'): if typeobj.Name.startswith('EPset_'): continue if DIRECT_PROPS: - for rel in typeobj.DefinesOccurrence: + for rel in (getattr(typeobj, 'DefinesOccurrence', ()) + getattr(typeobj, 'PropertyDefinitionOf', ())): for el in rel.RelatedObjects: - for p in typeobj.HasProperties: + for p in (_ for _ in typeobj.HasProperties if _.Name): def val(): try: return p.NominalValue[0] except: return p.EnumerationValues[0][0] - created_nodes[el].GetPrim().CreateAttribute(f'ifc5:properties:{p.Name}', getSdfType(val())).Set( + created_nodes[el].GetPrim().CreateAttribute(f'ifc5:properties:{p.Name.replace(" ", "").replace("-", "_").replace("/", "_").replace("(", "").replace(")", "")}', getSdfType(val())).Set( val() ) diff --git a/src/utils/python/populate_schema.py b/src/utils/python/populate_schema.py index bce61bf..9f987d5 100644 --- a/src/utils/python/populate_schema.py +++ b/src/utils/python/populate_schema.py @@ -7,53 +7,73 @@ "height": {"quantityKind": "Length"} } +class frozendict(dict): + def __key(self): + return frozenset((k,self[k]) for k in self) + + def __hash__(self): + return hash(self.__key()) + + def __eq__(self, other): + return self.__key() == other.__key() + def make_schema(v, path=[]): if isinstance(v, dict): - return { + return frozendict({ "dataType": "Object", - "objectRestrictions": { - "values": {k: make_schema(v, [*path, k]) for k, v in v.items()} - } - } + "objectRestrictions": frozendict({ + "values": frozendict({k: make_schema(v, [*path, k]) for k, v in v.items()}) + }) + }) elif isinstance(v, list): if set(map(type, v)) == {int, float}: - return { + return frozendict({ "dataType": "Array", - "arrayRestrictions": { - "value": { + "arrayRestrictions": frozendict({ + "value": frozendict({ "dataType": "Real" - } - } - } + }) + }) + }) else: assert len(set(map(type, v))) == 1 - return { + schemas = set(make_schema(i, [*path, k]) for i in v) + if len(schemas) == 1: + element_schema = next(iter(schemas)) + else: + element_schema = frozendict({ + "dataType": "Union", + "unionRestrictions": frozendict({ + "values": tuple(sorted(schemas, key=str)) + }) + }) + return frozendict({ "dataType": "Array", - "arrayRestrictions": { - "value": make_schema(v[0], [*path, k]) - } - } + "arrayRestrictions": frozendict({ + "value": element_schema + }) + }) elif isinstance(v, float): - return { + return frozendict({ "dataType": "Real", **known_quants.get(path[-1].split('::')[-1], {}) - } + }) elif isinstance(v, bool): - return { + return frozendict({ "dataType": "Boolean" - } + }) elif isinstance(v, int): if "points" in path or "transform" in path: - return { + return frozendict({ "dataType": "Real" - } - return { + }) + return frozendict({ "dataType": "Integer" - } + }) elif isinstance(v, str): - return { + return frozendict({ "dataType": "String" - } + }) else: breakpoint() @@ -62,7 +82,7 @@ def unify_schemas(left, right): if None in (left, right): return left or right types = set(map(type, (left, right))) - assert types in ({str}, {dict}) + assert types in ({str}, {frozendict}) if types == {str}: if {left, right} == {'Integer', 'Real'}: return 'Real' diff --git a/src/utils/python/rewrite_materials.py b/src/utils/python/rewrite_materials.py index f4c4ace..a73deed 100644 --- a/src/utils/python/rewrite_materials.py +++ b/src/utils/python/rewrite_materials.py @@ -13,7 +13,7 @@ def it(): mat = d['attributes']['usd::usdshade::materialbindingapi'] assert len(d['attributes']) == 1 del d['attributes'] - entity_type = next(filter(None, (x.get('attributes', {}).get('bsi::ifc::v5a::class', {}).get('code') for x in obj['data'] if x['path'] == d['path']))) + entity_type = next(filter(None, (x.get('attributes', {}).get('bsi::ifc::v5a::class', {}).get('code') for x in obj['data'] if x['path'] == d['path'])), None) if entity_type == 'IfcWindow': # skip the window material associations, split_window_bodies takes care of those in an aggregation to_remove.add(next(iter(mat.values()))['ref']) diff --git a/src/utils/python/transform_prealpha_to_alpha.py b/src/utils/python/transform_prealpha_to_alpha.py index 7d89df5..e2c13c5 100644 --- a/src/utils/python/transform_prealpha_to_alpha.py +++ b/src/utils/python/transform_prealpha_to_alpha.py @@ -1,3 +1,4 @@ +import ast import functools import itertools import operator @@ -75,6 +76,11 @@ def transform(k, v): if k.startswith("usd") and not k.startswith("usd::"): k = "usd::" + k + try: + v = json.loads(ast.literal_eval(v)) + except: + pass + if isinstance(v, dict): v = transform_attributes(v) if not v: diff --git a/src/utils/python/usda-to-json.py b/src/utils/python/usda-to-json.py index 6cb85c8..e471524 100644 --- a/src/utils/python/usda-to-json.py +++ b/src/utils/python/usda-to-json.py @@ -25,6 +25,7 @@ REFERENCE: /<[^>]+>/ value: STRING + | SQUOTSTRING | NUMBER | REFERENCE | "true" -> true @@ -34,6 +35,7 @@ NAME: /[A-Za-z_][A-Za-z_:\.\d]*/ STRING: /".*?"/ + SQUOTSTRING: /'.*?'/ NUMBER: /-?\d+(\.\d+)?([eE][+-]?\d+)?/ meta: "(" (STRING | (/[A-Za-z_]+/ "=" value))+ ")" @@ -107,7 +109,12 @@ def meta(self, items): @v_args(inline=True) def STRING(self, s): - return s.strip('"') + if s.startswith('"'): + return s.strip('"') + elif s.startswith("'"): + return s.strip("'") + else: + return s @v_args(inline=True) def NUMBER(self, n): @@ -190,6 +197,10 @@ def parse_usda_to_dict(usda_content): # @todo rename to stay consistent with USD? grouped_attrs['points:array'] = {'positions': grouped_attrs['points:array']['points']} for ns, ats in grouped_attrs.items(): + if ns == 'ifc5' and len(ats) == 1: + kk, vv = next(iter(ats.items())) + ns = f'{ns}:{kk}' + ats = vv overs.append({ 'def': 'over', 'name': node['name'], diff --git a/src/viewer/profile.ts b/src/viewer/profile.ts new file mode 100644 index 0000000..1c3245f --- /dev/null +++ b/src/viewer/profile.ts @@ -0,0 +1,209 @@ +type Point = [number, number]; + +interface Polyline { + "bsi::ifc::geometry::procedural::polyline": { + Points: Point[]; + }; +} + +interface CircularArc { + "bsi::ifc::geometry::procedural::circular_arc": { + Points: [Point, Point, Point]; + }; +} + +interface CompositeCurve { + "bsi::ifc::geometry::procedural::composite_curve": { + Segments: Array; + }; +} + +interface Rectangle { + "bsi::ifc::geometry::procedural::rectangle": { + position?: { Location?: Point }; + Width: number; + Height: number; + }; +} + +export type Profile = + | { "bsi::ifc::geometry::procedural::composite_profile": { Profiles: Profile[] } } + | { "bsi::ifc::geometry::procedural::profile_with_voids": { exterior: Profile; Interior?: Profile[] } } + | Rectangle + | CompositeCurve + | Polyline; + +type Bounds = { minX: number; minY: number; maxX: number; maxY: number }; + +function newBounds(): Bounds { + return { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }; +} +function addPt(b: Bounds, p: Point) { + b.minX = Math.min(b.minX, p[0]); + b.minY = Math.min(b.minY, p[1]); + b.maxX = Math.max(b.maxX, p[0]); + b.maxY = Math.max(b.maxY, p[1]); +} + +function threePointArcParams(p0: Point, pm: Point, p1: Point) { + const [x1, y1] = p0; const [x2, y2] = pm; const [x3, y3] = p1; + const a = x1 * (y2 - y3) - y1 * (x2 - x3) + x2 * y3 - x3 * y2; + + const x1sqy1sq = x1 * x1 + y1 * y1; + const x2sqy2sq = x2 * x2 + y2 * y2; + const x3sqy3sq = x3 * x3 + y3 * y3; + const bx = x1sqy1sq * (y2 - y3) + x2sqy2sq * (y3 - y1) + x3sqy3sq * (y1 - y2); + const by = x1sqy1sq * (x3 - x2) + x2sqy2sq * (x1 - x3) + x3sqy3sq * (x2 - x1); + const cx = -bx / (2 * a); + const cy = -by / (2 * a); + const r = Math.hypot(x1 - cx, y1 - cy); + + const aStart = Math.atan2(y1 - cy, x1 - cx); + const aMid = Math.atan2(y2 - cy, x2 - cx); + const aEnd = Math.atan2(y3 - cy, x3 - cx); + + // Choose direction so mid-angle lies on the arc sweep + const norm = (t: number) => (t + 2 * Math.PI) % (2 * Math.PI); + const dCCW = norm(aEnd - aStart); + const onCCW = norm(aMid - aStart) <= dCCW; + const ccw = onCCW; + const sweepAngle = ccw ? dCCW : norm(aStart - aEnd); + const largeArcFlag = sweepAngle <= Math.PI ? 1 : 0; + + // Because we flip Y later via scale(1, -1), use sweepFlag=1 for math-CCW + const sweepFlag = !ccw ? 1 : 0; + + return { r, largeArcFlag, sweepFlag }; +} + +function polylinePath(points: Point[], bounds: Bounds): string { + if (!points.length) return ""; + points.forEach(p => addPt(bounds, p)); + const [x0, y0] = points[0]; + const moves = [`M ${x0} ${y0}`]; + for (let i = 1; i < points.length; i++) { + const [x, y] = points[i]; + moves.push(`L ${x} ${y}`); + } + return moves.join(" "); +} + +function arcPath(arc: CircularArc["bsi::ifc::geometry::procedural::circular_arc"], bounds: Bounds): string { + const [p0, pm, p1] = arc.Points; + addPt(bounds, p0); addPt(bounds, pm); addPt(bounds, p1); + const { r, largeArcFlag, sweepFlag } = threePointArcParams(p0, pm, p1); + return `M ${p0[0]} ${p0[1]} A ${r} ${r} 0 ${largeArcFlag} ${sweepFlag} ${p1[0]} ${p1[1]}`; +} + +function rectanglePath(rect: Rectangle["bsi::ifc::geometry::procedural::rectangle"], bounds: Bounds): string { + let [x, y] = rect.position?.Location ?? [0, 0]; + const w = rect.Width, h = rect.Height; + x -= w / 2.; + y -= h / 2.; + addPt(bounds, [x, y]); + addPt(bounds, [x + w, y + h]); + return `M ${x} ${y} L ${x + w} ${y} L ${x + w} ${y + h} L ${x} ${y + h} Z`; +} + +function renderProfileToPaths(profile: Profile, bounds: Bounds, out: string[]): void { + const k = Object.keys(profile)[0] as keyof Profile; + const v: any = (profile as any)[k]; + + switch (k) { + case "bsi::ifc::geometry::procedural::polyline": { + const d = polylinePath(v.Points, bounds); + if (d) out.push(d); + return; + } + case "bsi::ifc::geometry::procedural::circular_arc": { + const d = arcPath(v, bounds); + if (d) out.push(d); + return; + } + case "bsi::ifc::geometry::procedural::composite_curve": { + const segs: Array = v.Segments ?? []; + for (const seg of segs) { + const sk = Object.keys(seg)[0]; + const sv: any = (seg as any)[sk]; + if (sk === "bsi::ifc::geometry::procedural::polyline") { + const d = polylinePath(sv.Points, bounds); + if (d) out.push(d); + } else if (sk === "bsi::ifc::geometry::procedural::circular_arc") { + const d = arcPath(sv, bounds); + if (d) out.push(d); + } + } + return; + } + case "bsi::ifc::geometry::procedural::rectangle": { + const d = rectanglePath(v, bounds); + out.push(d); + return; + } + case "bsi::ifc::geometry::procedural::profile_with_voids": { + // Stroke-only: render exterior and each interior as separate paths + renderProfileToPaths(v.exterior, bounds, out); + (v.Interior ?? []).forEach((p: Profile) => renderProfileToPaths(p, bounds, out)); + return; + } + case "bsi::ifc::geometry::procedural::composite_profile": { + (v.Profiles ?? []).forEach((p: Profile) => renderProfileToPaths(p, bounds, out)); + return; + } + default: + return; + } +} + +export interface SvgOptions { + stroke?: string; + strokeWidth?: number; + pixelSize?: number; + pad?: number; +} + +/** + * Build a stroke-only SVG string from the procedural geometry. + */ +export function buildSVGFromProceduralGeometry( + input: Profile, + opts: SvgOptions = {} +): string { + const stroke = opts.stroke ?? "black"; + const strokeWidth = opts.strokeWidth ?? 0.0008; + const pad = opts.pad ?? 0.002; + const pixelSize = opts.pixelSize ?? 512; + + const bounds = newBounds(); + const pathDs: string[] = []; + + renderProfileToPaths(input, bounds, pathDs); + + if (!pathDs.length || !isFinite(bounds.minX)) { + return ``; + } + + // Pad bounds + const minX = bounds.minX - pad; + const minY = bounds.minY - pad; + const maxX = bounds.maxX + pad; + const maxY = bounds.maxY + pad; + + const width = maxX - minX; + const height = maxY - minY; + + const tx = -minX; + const ty = -minY; + + const paths = pathDs.map(d => ``).join("\n "); + + return ` + + + ${paths} + +`.trim(); +} diff --git a/src/viewer/render.ts b/src/viewer/render.ts index f1d8bc2..82cef49 100644 --- a/src/viewer/render.ts +++ b/src/viewer/render.ts @@ -8,6 +8,7 @@ import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; import { PCDLoader } from 'three/addons/loaders/PCDLoader.js'; +import { buildSVGFromProceduralGeometry, Profile } from './profile'; let controls, renderer, scene, camera; type datastype = [string, IfcxFile][]; @@ -212,6 +213,11 @@ function tryCreateMeshGltfMaterial(path: ComposedObject[]) { material.color = new THREE.Color(baseColorFactor[0], baseColorFactor[1], baseColorFactor[2]); } + if (baseColorFactor && baseColorFactor.length >= 4 && baseColorFactor[3] < 1.0) { + material.opacity = baseColorFactor[3]; + material.transparent = true; + } + let metallicFactor = pbrMetallicRoughness["metallicFactor"]; if (metallicFactor !== undefined) { material.metalness = metallicFactor; @@ -438,6 +444,7 @@ const icons = { 'pcd::base64': 'grain', 'points::array::positions': 'grain', 'points::base64::positions': 'grain', + 'bsi::ifc::procedural_geometry::has_profile': 'format_italic', }; function handleClick(prim, pathMapping, root) { @@ -446,7 +453,7 @@ function handleClick(prim, pathMapping, root) { container.innerHTML = ""; const table = document.createElement("table"); table.setAttribute("border", "0"); - const entries = [["name", prim.name], ...Object.entries(prim.attributes).filter(([k, _]) => !k.startsWith('__internal_'))]; + const entries = [["name", prim.name], ...Object.entries(prim.attributes || {}).filter(([k, _]) => !k.startsWith('__internal_'))]; const format = (value) => { if (Array.isArray(value)) { let N = document.createElement('span'); @@ -483,6 +490,20 @@ function handleClick(prim, pathMapping, root) { } } return a; + } else if (ks.length == 1 && ks[0].indexOf("procedural") !== -1) { + const svgString = buildSVGFromProceduralGeometry(value as Profile, { pixelSize: 240, stroke: "#222", strokeWidth: 0.001 }); + const parser = new DOMParser(); + const doc = parser.parseFromString(svgString, "image/svg+xml"); + let container = document.createElement('div'); + let left = document.createElement('div'); + left.style.float = 'left'; + left.appendChild(doc.documentElement); + let right = document.createElement('div'); + right.innerHTML = `${JSON.stringify(value, null, 4).replace(/\n\s+([\-\+\d\.e]+|\])(,?)(?=\n)/g, '$1$2')}` + right.style.float = 'right'; + container.appendChild(left); + container.appendChild(right); + return container; } else { return document.createTextNode(JSON.stringify(value)); }