Compare commits

...

29 Commits

Author SHA1 Message Date
Andrej730 3d7e8d7c6c Fixed #4259
Result of DeepDiff contain ordered sets. Also added fallback for usual sets to lists just in case, should be safe.
2024-01-30 15:41:08 +05:00
Andrej730 a701840826 Fixed error adding a boolean
It occured if active object was IFC object and second selected object was just Blender object.
2024-01-30 14:40:07 +05:00
Andrej730 5de2ac9042 black format 2024-01-30 14:36:35 +05:00
Andrej730 573e2626ad Fix test Model.get_manual_booleans after we added pset to store them 2024-01-30 14:36:35 +05:00
Andrej730 9de59afd49 Fix #4267 and add tests
Crash was caused by unmark_manual_booleans accessing boolean element after they were deleted from IFC
2024-01-30 14:36:35 +05:00
Andrej730 74a9671075 Update ui.py 2024-01-30 14:36:35 +05:00
Andrej730 799658ff41 display active representation presentation layer in UI
example - https://i.imgur.com/mpnoqPH.png
2024-01-30 14:36:35 +05:00
Andrej730 bd64f42a54 remove_representation to consider representation item's layers too
and purge layers if they are out of items as they become invalid
2024-01-30 14:36:35 +05:00
Andrej730 8eab7f155e Small presentation layers UI fixes 2024-01-30 14:36:35 +05:00
Andrej730 5351966430 access layer assignments from inverse attribute instead of going through representation inverses 2024-01-30 14:36:35 +05:00
Andrej730 2663c079f4 test for removing representation items 2024-01-29 16:47:17 +05:00
Andrej730 6747bd9c8f UI to remove representation items
example - https://i.imgur.com/jJDpIQP.png
2024-01-29 16:47:16 +05:00
Andrej730 6ece295be4 tests for creating shape aspects and adding items 2024-01-29 15:52:40 +05:00
Andrej730 64a9f85f25 create new shape aspects from UI
example - https://i.imgur.com/BJJZWrC.png
2024-01-29 15:52:39 +05:00
Andrej730 d8fa853308 edit shape aspect attributes from UI
example - https://i.imgur.com/SzUEn6r.png
2024-01-29 15:52:39 +05:00
Andrej730 ce37c49624 Fix #4262 after 0da3270c7 2024-01-29 11:13:22 +05:00
Andrej730 0da3270c7f UI for changing representation item's shape aspect
Example - https://imgur.com/a/tN7hCYz
2024-01-26 17:32:46 +05:00
Andrej730 fda6fc6c48 geometry.remove_representation documentation 2024-01-26 17:20:39 +05:00
Andrej730 3865f01df9 operator to remove representation item from shape aspect 2024-01-26 17:20:39 +05:00
Andrej730 6bf61d7163 Simple UI to display repr item shape aspect
Example - https://i.imgur.com/YEAE9zU.png
2024-01-26 15:27:05 +05:00
Andrej730 b8ad73668f BBIM to print console errors in case IFC file is failed to load 2024-01-26 14:54:51 +05:00
Andrej730 b7a3dd4164 black format 2024-01-26 14:54:50 +05:00
Bruno Postle 566fd443db IfcGit avoid leaving stray .git/config.lock files 2024-01-25 23:30:00 +00:00
Andrej730 51b5a507cf shape builder docs 2024-01-25 16:46:38 +05:00
Andrej730 a44357dad5 shape builder polyline example and tests 2024-01-25 16:46:34 +05:00
Andrej730 8e792ebb50 UI for changing styles for representation items
Example - https://imgur.com/a/SQh6rR2
2024-01-25 15:17:44 +05:00
Andrej730 352321364c fix couple building docs errors / warnings 2024-01-24 16:38:53 +05:00
Andrej730 2ab32e41b2 shape builder docs fixes 2024-01-24 16:38:53 +05:00
Andrej730 3fbd9d7cdf IFC4 Landscape Library
Created IFC library with simple trees, shrubs and hedges - with both 2d and 3d representations. Example - https://i.imgur.com/pOjh1si.png
Now it's available along with the furniture library when creating new project - https://i.imgur.com/Ho0B5Gn.png
2024-01-24 16:38:52 +05:00
29 changed files with 2361 additions and 160 deletions
@@ -0,0 +1,993 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1');
FILE_NAME('/dev/null','2024-01-24T15:32:17+05:00',(),(),'IfcOpenShell v0.7.0-6c9e130ca','IfcOpenShell v0.7.0-6c9e130ca','Nobody');
FILE_SCHEMA(('IFC4'));
ENDSEC;
DATA;
#1=IFCPROJECT('3GRx5GJtv7EvI86hmjeQD6',$,'Landscape Assets Library',$,$,$,$,(#10,#14),#5);
#2=IFCPROJECTLIBRARY('1Go1D2HIr9AR4M6PdJb8DW',$,'Landscape Assets Library',$,$,$,$,$,$);
#3=IFCRELDECLARES('2Nc$sSRrvCzOJbe4Q6ZcVa',$,$,$,#1,(#2));
#4=IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#5=IFCUNITASSIGNMENT((#4));
#6=IFCCARTESIANPOINT((0.,0.,0.));
#7=IFCDIRECTION((0.,0.,1.));
#8=IFCDIRECTION((1.,0.,0.));
#9=IFCAXIS2PLACEMENT3D(#6,#7,#8);
#10=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,$);
#11=IFCCARTESIANPOINT((0.,0.));
#12=IFCDIRECTION((1.,0.));
#13=IFCAXIS2PLACEMENT2D(#11,#12);
#14=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Plan',2,1.E-05,#13,$);
#15=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#10,$,.MODEL_VIEW.,$);
#16=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Plan',*,*,*,*,#14,$,.PLAN_VIEW.,$);
#17=IFCCARTESIANPOINTLIST2D(((-331.408782958984,488.559936523438),(-428.486114501953,371.370391845703),(-408.744873046875,331.425659179688),(-492.345001220703,263.470184326172),(-519.991760253906,89.2266616821289),(-366.53076171875,65.1004943847656),(-523.9287109375,51.0255508422852),(-542.778625488281,-161.150390625),(-455.430816650391,-198.061676025391),(-467.317413330078,-264.261047363281),(-389.842987060547,-378.319213867188),(-351.178894042969,-382.372741699219),(-243.823715209961,-498.601684570312),(-171.287063598633,-509.852447509766),(-182.036499023438,-454.125518798828),(-123.127815246582,-538.493591308594),(208.583557128906,-495.693969726562),(174.199142456055,-387.101898193359),(269.968353271484,-457.362365722656),(517.720397949219,-208.39501953125),(467.592559814453,-165.981643676758),(535.54443359375,-138.483825683594),(546.240173339844,47.7887229919434),(425.388610839844,29.4520435333252),(514.287658691406,107.907821655273),(467.776489257812,312.002685546875),(374.896423339844,365.066589355469),(325.083190917969,461.613433837891),(224.657806396484,496.0244140625),(105.845329284668,424.517761230469),(191.164672851562,514.677307128906),(-7.41858577728271,553.592407226562),(-105.371849060059,531.902709960938),(-180.417175292969,499.200317382812)));
#18=IFCINDEXEDPOLYCURVE(#17,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#19=IFCCARTESIANPOINTLIST3D(((80.,0.,0.),(40.,69.2820323027551,0.),(-40.,69.2820323027551,0.),(-80.,9.79717439317883E-15,0.),(-40.,-69.2820323027551,0.),(40.,-69.2820323027551,0.),(80.,0.,280.),(40.,69.2820323027551,280.),(-40.,69.2820323027551,280.),(-80.,9.79717439317883E-15,280.),(-40.,-69.2820323027551,280.),(40.,-69.2820323027551,280.),(570.140986817674,-5.11998806339175,502.765430824539),(261.339072714044,511.863483235935,520.441255965265),(-271.449977559115,464.840881207563,498.631051036932),(-577.400357563209,-18.0002392785791,529.745674601363),(-246.747896537159,-522.096293601777,523.07445182747),(289.929723989709,-497.828722152031,481.563368832141),(502.264135660384,-3.10815712380199,727.667741239885),(256.486268377103,397.638199139059,733.570036889682),(-210.099579404528,457.859720268934,722.445245365077),(-522.479901100414,-35.7080296205946,687.931736233252),(-213.081169792834,-438.257812253687,704.648197605265),(273.503462940155,-437.429578762916,717.812431534607),(409.72756228227,-31.3204193188668,937.51589967911),(231.939555298324,334.085354425246,911.578097173966),(-213.440011711198,325.481782873574,931.184023328963),(-391.4385670944,11.3681475906559,933.839400395571),(-181.597613330968,-384.045646583411,936.269525762716),(198.107253544529,-351.52926490917,903.558501964971),(358.836914477244,-29.0443800107266,1124.54961826854),(191.636382145782,325.816574427016,1143.76409675514),(-175.686180114122,275.257306965059,1132.35007279295),(-330.55780048986,-23.1508504281077,1121.17416888324),(-172.687090174965,-317.707089809191,1159.279616419),(192.616008554028,-273.601791847896,1147.14103266758),(252.691797114565,-4.70084047240072,1330.07490310776),(147.138603790187,216.221351494253,1352.71275883304),(-162.078730999078,224.60205813657,1371.67941135993),(-271.544406853979,26.607279268613,1378.19571732018),(-150.451939922955,-226.516554345382,1395.27272058484),(133.281231324475,-220.990480915293,1334.23398662872),(187.5691337229,-2.77622907865673,1575.7384942221),(88.4380124532162,169.216774598146,1585.64117034361),(-94.8941720337192,139.038794764388,1578.6341137138),(-154.588503036945,-6.10749408831602,1549.40002660187),(-129.962875945536,-160.551322551302,1550.49839466833),(64.8441918513045,-191.270989336927,1579.55078264226),(0.05,0.,1800.),(0.025,0.0433012701892219,1800.),(-0.025,0.0433012701892219,1800.),(-0.05,6.12323399573677E-18,1800.),(-0.025,-0.0433012701892219,1800.),(0.025,-0.0433012701892219,1800.)));
#20=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#21=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#22=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#23=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#24=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#25=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#26=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#27=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#28=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#29=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#30=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#31=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#32=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#33=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#34=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#35=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#36=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#37=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#38=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#39=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#40=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#41=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#42=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#43=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#44=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#45=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#46=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#47=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#48=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#49=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#50=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#51=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#52=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#53=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#54=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#55=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#56=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#57=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#58=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#59=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#60=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#61=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#62=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#63=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#64=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#65=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#66=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#67=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#68=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#69=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#70=IFCPOLYGONALFACESET(#19,$,(#20,#21,#22,#23,#24,#25,#26,#27,#28,#29,#30,#31,#32,#33,#34,#35,#36,#37,#38,#39,#40,#41,#42,#43,#44,#45,#46,#47,#48,#49,#50,#51,#52,#53,#54,#55,#56,#57,#58,#59,#60,#61,#62,#63,#64,#65,#66,#67,#68,#69),$);
#71=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#18));
#72=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#70));
#73=IFCGEOGRAPHICELEMENTTYPE('34zHVx8cX0dRoaynJ1QKTg',$,'Cone Tree (1.8m)',$,$,$,(#78,#83),$,$,.NOTDEFINED.);
#74=IFCCARTESIANPOINT((0.,0.,0.));
#75=IFCDIRECTION((1.,0.,0.));
#76=IFCDIRECTION((0.,0.,1.));
#77=IFCAXIS2PLACEMENT3D(#74,#76,#75);
#78=IFCREPRESENTATIONMAP(#77,#72);
#79=IFCCARTESIANPOINT((0.,0.,0.));
#80=IFCDIRECTION((1.,0.,0.));
#81=IFCDIRECTION((0.,0.,1.));
#82=IFCAXIS2PLACEMENT3D(#79,#81,#80);
#83=IFCREPRESENTATIONMAP(#82,#71);
#84=IFCRELDECLARES('2hc5gFJQT6VP_pTBscCuS_',$,$,$,#2,(#840,#409,#680,#208,#613,#73,#342,#773,#275,#479,#742,#907,#711,#141,#546,#974,#444));
#85=IFCCARTESIANPOINTLIST2D(((-1281.64282226562,1889.38659667969),(-1657.06579589844,1436.1845703125),(-1580.72131347656,1281.70812988281),(-1904.02453613281,1018.90686035156),(-2010.94165039062,345.062408447266),(-1417.46850585938,251.760314941406),(-2026.16674804688,197.328903198242),(-2099.06420898438,-623.209899902344),(-1761.26782226562,-765.955322265625),(-1807.236328125,-1021.96527099609),(-1507.62292480469,-1463.05749511719),(-1358.09887695312,-1478.73352050781),(-942.928833007812,-1928.220703125),(-662.411010742188,-1971.73022460938),(-703.981872558594,-1756.21984863281),(-476.166870117188,-2082.49291992188),(806.646179199219,-1916.97583007812),(673.672790527344,-1497.02233886719),(1044.03686523438,-1768.73767089844),(2002.15771484375,-805.917053222656),(1808.30041503906,-641.893615722656),(2071.087890625,-535.552490234375),(2112.45092773438,184.811248779297),(1645.0869140625,113.898612976074),(1988.88244628906,417.307220458984),(1809.01171875,1206.59436035156),(1449.82067871094,1411.80627441406),(1257.18005371094,1785.17761230469),(868.809387207031,1918.25366210938),(409.3310546875,1641.71911621094),(739.282836914062,1990.38916015625),(-28.6895751953125,2140.8837890625),(-407.5,2057.00415039062),(-697.719543457031,1930.53576660156)));
#86=IFCINDEXEDPOLYCURVE(#85,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#87=IFCCARTESIANPOINTLIST3D(((220.,0.,0.),(110.,190.525588832576,0.),(-110.,190.525588832577,0.),(-220.,2.69422295812418E-14,0.),(-110.,-190.525588832576,0.),(110.,-190.525588832576,0.),(220.,0.,740.),(110.,190.525588832576,740.),(-110.,190.525588832577,740.),(-220.,2.69422295812418E-14,740.),(-110.,-190.525588832576,740.),(110.,-190.525588832576,740.),(2227.84155681395,-42.6665671949312,2823.99763782354),(916.158939283701,2080.25825808339,2971.29618066292),(-1000.41647965929,1688.40324118029,2789.54447292681),(-2288.33631302674,-150.00199398816,3048.8330026304),(-794.565804476328,-2165.53167779874,2993.23947951463),(1154.41436658091,-1963.30191571753,2647.31378788689),(1998.64557494764,-25.9013093650166,4925.80260557047),(1043.94112536474,1419.75032646046,4974.98840265211),(-657.385383926618,1921.59633587608,4882.28180661374),(-2167.11028694789,-297.566913504955,4594.66923051519),(-682.231970495834,-1758.24710241569,4733.97307528197),(1185.75108005685,-1751.34515665926,4843.67502469316),(1563.95190790781,-261.00349432389,6902.15630684973),(1007.60740526381,1181.51272302971,6686.0079526402),(-853.444542037762,1109.81629343244,6849.3906705985),(-1411.54361467555,94.7345632554656,6871.51881282023),(-588.091222202507,-1597.84849101442,6891.76985754645),(725.67155731552,-1326.87864372908,6619.17799256523),(1476.3076206437,-242.036500089388,8688.38967604738),(839.969851214854,1403.97565889549,8848.51033010232),(-707.051500951019,982.648430045852,8753.39346375077),(-1240.6483374155,-192.923753567565,8660.26093116989),(-682.059084791378,-1336.39662041362,8977.80632730116),(848.133404616898,-968.852470736159,8876.65146270604),(928.209420399157,-39.1736706033394,10628.7194306599),(637.377253807116,782.05157030683,10817.3682283706),(-761.878313881205,851.890792326142,10975.4236660946),(-1085.31450156094,221.727327238442,11029.7262157634),(-664.988388246851,-867.844927399578,11172.0345763022),(521.899149926181,-821.794315482163,10663.3784600012),(721.965003246392,-23.1352423221394,12903.5350708985),(316.42788155458,681.716198690303,12986.057371911),(-370.229211392105,430.233033408991,12927.6652333293),(-447.126414196768,-50.8957840693003,12684.0478407298),(-662.468410657245,-609.504098299938,12693.2009079504),(119.812709871982,-865.501321513485,12935.3041410664),(0.05,0.,15000.),(0.025,0.0433012701892219,15000.),(-0.025,0.0433012701892219,15000.),(-0.05,6.12323399573677E-18,15000.),(-0.025,-0.0433012701892219,15000.),(0.025,-0.0433012701892219,15000.)));
#88=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#89=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#90=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#91=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#92=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#93=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#94=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#95=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#96=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#97=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#98=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#99=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#100=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#101=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#102=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#103=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#104=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#105=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#106=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#107=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#108=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#109=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#110=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#111=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#112=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#113=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#114=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#115=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#116=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#117=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#118=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#119=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#120=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#121=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#122=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#123=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#124=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#125=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#126=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#127=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#128=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#129=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#130=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#131=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#132=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#133=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#134=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#135=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#136=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#137=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#138=IFCPOLYGONALFACESET(#87,$,(#88,#89,#90,#91,#92,#93,#94,#95,#96,#97,#98,#99,#100,#101,#102,#103,#104,#105,#106,#107,#108,#109,#110,#111,#112,#113,#114,#115,#116,#117,#118,#119,#120,#121,#122,#123,#124,#125,#126,#127,#128,#129,#130,#131,#132,#133,#134,#135,#136,#137),$);
#139=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#86));
#140=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#138));
#141=IFCGEOGRAPHICELEMENTTYPE('1up5YjiS1CSvOopNo9qhzA',$,'Cone Tree (15m)',$,$,$,(#146,#151),$,$,.NOTDEFINED.);
#142=IFCCARTESIANPOINT((0.,0.,0.));
#143=IFCDIRECTION((1.,0.,0.));
#144=IFCDIRECTION((0.,0.,1.));
#145=IFCAXIS2PLACEMENT3D(#142,#144,#143);
#146=IFCREPRESENTATIONMAP(#145,#140);
#147=IFCCARTESIANPOINT((0.,0.,0.));
#148=IFCDIRECTION((1.,0.,0.));
#149=IFCDIRECTION((0.,0.,1.));
#150=IFCAXIS2PLACEMENT3D(#147,#149,#148);
#151=IFCREPRESENTATIONMAP(#150,#139);
#152=IFCCARTESIANPOINTLIST2D(((-498.579620361328,735.001647949219),(-644.625122070312,558.698791503906),(-614.925903320312,498.60498046875),(-740.696044921875,396.37109375),(-782.288513183594,134.234802246094),(-551.41796875,97.9387969970703),(-788.211303710938,76.7640991210938),(-816.569641113281,-242.43864440918),(-685.161376953125,-297.968902587891),(-703.043884277344,-397.560852050781),(-586.489440917969,-569.15283203125),(-528.322204589844,-575.251037597656),(-366.814422607422,-750.108703613281),(-257.688507080078,-767.03466796875),(-273.860229492188,-683.197692871094),(-185.236541748047,-810.123107910156),(313.798278808594,-745.734313964844),(262.069519042969,-582.365661621094),(406.147064208984,-688.067260742188),(778.871398925781,-313.5146484375),(703.457824707031,-249.706893920898),(805.686340332031,-208.338500976562),(821.777282714844,71.8945388793945),(639.965148925781,44.3083839416504),(773.707153320312,162.339202880859),(703.734558105469,469.384552001953),(564.003479003906,549.215209960938),(489.063201904297,694.462707519531),(337.980773925781,746.2314453125),(159.236328125,638.655029296875),(287.592864990234,774.293273925781),(-11.1607036590576,832.838073730469),(-158.524017333984,800.207580566406),(-271.424072265625,751.009338378906)));
#153=IFCINDEXEDPOLYCURVE(#152,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#154=IFCCARTESIANPOINTLIST3D(((110.,0.,0.),(55.,95.2627944162882,0.),(-55.,95.2627944162883,0.),(-110.,1.34711147906209E-14,0.),(-55.,-95.2627944162882,0.),(55.,-95.2627944162882,0.),(110.,0.,320.),(55.,95.2627944162882,320.),(-55.,95.2627944162883,320.),(-110.,1.34711147906209E-14,320.),(-55.,-95.2627944162882,320.),(55.,-95.2627944162882,320.),(864.280518937983,-14.2221890649771,1004.18968879832),(366.2196464279,798.785843488237,1053.28920307812),(-394.305493219765,668.167504520537,992.705300499414),(-884.445437675581,-50.0006646627198,1079.13481040061),(-325.688601492109,-827.210316726686,1060.60363602869),(445.638122193637,-759.800396032949,945.295072152772),(771.659636093658,-8.63376978833887,1694.31515423778),(400.702597343804,564.567676396979,1710.71041993166),(-271.850683531095,731.84967953552,1679.8082212522),(-827.814540093743,-99.1889711683184,1583.93736255268),(-280.132879054167,-677.399935048722,1630.37197747494),(447.972582241171,-675.099286463246,1666.93929394534),(610.539524858158,-87.0011647746299,2342.62353085467),(380.480246199047,471.106285369781,2270.57407945149),(-329.092625123698,447.207475504026,2325.0349854376),(-559.736760447407,31.5781877518219,2332.41103284484),(-240.641518511947,-609.88487469802,2339.16138108691),(286.501630216284,-519.561592269572,2248.29742609317),(565.102540214566,-80.6788333631295,2927.55846344436),(316.489950404951,531.211740774762,2980.93201479601),(-272.18383365034,390.769331158215,2949.22639267883),(-486.549445805167,-64.3079178558549,2918.18221515187),(-263.853028263793,-508.685394614137,3024.03068052896),(319.211134872299,-386.170678054984,2990.31239233058),(366.18091791083,-13.0578902011131,3563.85885783901),(240.847973491261,309.854854694926,3626.74179040925),(-282.348326849291,333.134595368031,3679.42693631726),(-418.54927829809,73.9091090794806,3697.52778620685),(-250.051684971173,-338.452640392509,3744.96390638646),(202.355272197616,-323.102436420037,3575.41186761945),(281.210556637686,-7.71174744071313,4311.65454744235),(125.753738295971,262.36087427247,4339.1619811132),(-143.687514908479,178.533152512032,4319.69793491929),(-189.597693621145,-16.9652613564334,4238.49213738614),(-241.100581330193,-238.290174142348,4241.54315979299),(60.215347735105,-323.622581880197,4322.24423749834),(0.05,0.,5000.),(0.025,0.0433012701892219,5000.),(-0.025,0.0433012701892219,5000.),(-0.05,6.12323399573677E-18,5000.),(-0.025,-0.0433012701892219,5000.),(0.025,-0.0433012701892219,5000.)));
#155=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#156=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#157=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#158=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#159=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#160=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#161=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#162=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#163=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#164=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#165=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#166=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#167=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#168=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#169=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#170=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#171=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#172=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#173=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#174=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#175=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#176=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#177=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#178=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#179=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#180=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#181=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#182=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#183=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#184=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#185=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#186=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#187=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#188=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#189=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#190=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#191=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#192=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#193=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#194=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#195=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#196=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#197=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#198=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#199=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#200=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#201=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#202=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#203=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#204=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#205=IFCPOLYGONALFACESET(#154,$,(#155,#156,#157,#158,#159,#160,#161,#162,#163,#164,#165,#166,#167,#168,#169,#170,#171,#172,#173,#174,#175,#176,#177,#178,#179,#180,#181,#182,#183,#184,#185,#186,#187,#188,#189,#190,#191,#192,#193,#194,#195,#196,#197,#198,#199,#200,#201,#202,#203,#204),$);
#206=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#153));
#207=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#205));
#208=IFCGEOGRAPHICELEMENTTYPE('1cYi681Jz1UQcLu0VCPumj',$,'Cone Tree (5m)',$,$,$,(#213,#218),$,$,.NOTDEFINED.);
#209=IFCCARTESIANPOINT((0.,0.,0.));
#210=IFCDIRECTION((1.,0.,0.));
#211=IFCDIRECTION((0.,0.,1.));
#212=IFCAXIS2PLACEMENT3D(#209,#211,#210);
#213=IFCREPRESENTATIONMAP(#212,#207);
#214=IFCCARTESIANPOINT((0.,0.,0.));
#215=IFCDIRECTION((1.,0.,0.));
#216=IFCDIRECTION((0.,0.,1.));
#217=IFCAXIS2PLACEMENT3D(#214,#216,#215);
#218=IFCREPRESENTATIONMAP(#217,#206);
#219=IFCCARTESIANPOINTLIST2D(((-117.312850952148,172.941558837891),(-151.676498413086,131.458541870117),(-144.688446044922,117.318817138672),(-174.28141784668,93.263786315918),(-184.067886352539,31.584659576416),(-129.745407104492,23.0444221496582),(-185.461486816406,18.062141418457),(-192.134033203125,-57.0443878173828),(-161.214447021484,-70.1103286743164),(-165.422088623047,-93.5437316894531),(-137.997512817383,-133.918304443359),(-124.311111450195,-135.353179931641),(-86.3092803955078,-176.496170043945),(-60.6325874328613,-180.478744506836),(-64.4376983642578,-160.752395629883),(-43.5850677490234,-190.617202758789),(73.8348922729492,-175.466888427734),(61.6634140014648,-137.027221679688),(95.5640106201172,-161.898178100586),(183.263854980469,-73.7681503295898),(165.519485473633,-58.7545623779297),(189.573257446289,-49.020824432373),(193.359359741211,16.9163608551025),(150.580032348633,10.4255018234253),(182.048736572266,38.1974563598633),(165.584594726562,110.443428039551),(132.706695556641,129.227111816406),(115.073692321777,163.402984619141),(79.5248870849609,175.583862304688),(37.4673728942871,150.271774291992),(67.6689071655273,182.186645507812),(-2.62604808807373,195.961898803711),(-37.2997703552246,188.284133911133),(-63.8644866943359,176.708084106445)));
#220=IFCINDEXEDPOLYCURVE(#219,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#221=IFCCARTESIANPOINTLIST3D(((0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(189.142441515039,-1.13777512519817,58.3923179610087),(89.297571714232,167.825915933192,62.3202791033923),(-91.5444394575811,157.376448815776,57.4735668970959),(-190.755635014047,-4.00005317301757,64.3879276891917),(-86.0550881193688,-170.099873792268,62.9054337394378),(95.651049775491,-164.707080136769,53.6807486293646),(196.799437554159,-0.69070158306711,117.259498053308),(99.5895411208377,162.136578649577,118.571119308818),(-89.2813880158209,175.51913890066,116.098943414462),(-201.291829874166,-7.93511769346546,108.4292747185),(-89.9439636576667,-171.163159341716,112.144043912281),(103.371139912627,-170.979107454878,115.069429229913),(198.976495321986,-6.96009318197039,172.781311039802),(105.50508636259,167.707783451086,167.017354927548),(-101.394076676563,165.795878661826,171.374227406436),(-194.912274169126,2.52625502014577,171.964311199016),(-94.3179881476225,-178.810070597345,172.504339058381),(97.9867970839694,-171.58420800307,165.235222658882),(198.408203217165,-6.45430666905036,223.233248504121),(101.919196032396,175.172031121757,227.503132612252),(-98.3747066920271,163.936638352433,224.966682842878),(-192.123955664413,-5.14463342846837,222.483148640721),(-97.7082422611035,-173.369923428907,230.951025870888),(102.136890789784,-163.568746104175,228.253562815018),(185.561140099533,-1.04463121608905,277.794422912835),(97.4011712126342,160.119291473642,282.825057518454),(-100.721199481277,161.981670727491,287.039869191095),(-189.750608930514,5.91272872635847,288.487937182262),(-98.1374681310272,-162.407114329449,292.282826796631),(94.3217551091426,-161.179098011651,278.71866369527),(181.830177864348,-0.61693979525705,341.275220938245),(89.7269657303444,158.975584278118,343.475815631913),(-91.161667859345,152.269366537283,341.9186919364),(-174.501148823025,-1.35722090851465,335.422228133748),(-98.9547131730822,-157.049928267708,335.666309926296),(84.4838944854751,-163.876520886736,342.122396142724),(0.05,0.,400.),(0.025,0.0433012701892219,400.),(-0.025,0.0433012701892219,400.),(-0.05,6.12323399573677E-18,400.),(-0.025,-0.0433012701892219,400.),(0.025,-0.0433012701892219,400.)));
#222=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#223=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#224=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#225=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#226=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#227=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#228=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#229=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#230=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#231=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#232=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#233=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#234=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#235=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#236=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#237=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#238=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#239=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#240=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#241=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#242=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#243=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#244=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#245=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#246=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#247=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#248=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#249=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#250=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#251=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#252=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#253=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#254=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#255=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#256=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#257=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#258=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#259=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#260=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#261=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#262=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#263=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#264=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#265=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#266=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#267=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#268=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#269=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#270=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#271=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#272=IFCPOLYGONALFACESET(#221,$,(#222,#223,#224,#225,#226,#227,#228,#229,#230,#231,#232,#233,#234,#235,#236,#237,#238,#239,#240,#241,#242,#243,#244,#245,#246,#247,#248,#249,#250,#251,#252,#253,#254,#255,#256,#257,#258,#259,#260,#261,#262,#263,#264,#265,#266,#267,#268,#269,#270,#271),$);
#273=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#220));
#274=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#272));
#275=IFCGEOGRAPHICELEMENTTYPE('1mO0fZa2b4sflxAiM3QTIb',$,'Hedge Small (0.4m)',$,$,$,(#280,#285),$,$,.NOTDEFINED.);
#276=IFCCARTESIANPOINT((0.,0.,0.));
#277=IFCDIRECTION((1.,0.,0.));
#278=IFCDIRECTION((0.,0.,1.));
#279=IFCAXIS2PLACEMENT3D(#276,#278,#277);
#280=IFCREPRESENTATIONMAP(#279,#274);
#281=IFCCARTESIANPOINT((0.,0.,0.));
#282=IFCDIRECTION((1.,0.,0.));
#283=IFCDIRECTION((0.,0.,1.));
#284=IFCAXIS2PLACEMENT3D(#281,#283,#282);
#285=IFCREPRESENTATIONMAP(#284,#273);
#286=IFCCARTESIANPOINTLIST2D(((-234.625701904297,345.883117675781),(-303.352996826172,262.917083740234),(-289.376892089844,234.637634277344),(-348.562835693359,186.527572631836),(-368.135772705078,63.169319152832),(-259.490814208984,46.0888442993164),(-370.922973632812,36.1242828369141),(-384.26806640625,-114.088775634766),(-322.428894042969,-140.220657348633),(-330.844177246094,-187.087463378906),(-275.995025634766,-267.836608886719),(-248.622222900391,-270.706359863281),(-172.618560791016,-352.992340087891),(-121.265174865723,-360.957489013672),(-128.875396728516,-321.504791259766),(-87.1701354980469,-381.234405517578),(147.669784545898,-350.933776855469),(123.32682800293,-274.054443359375),(191.128021240234,-323.796356201172),(366.527709960938,-147.53630065918),(331.038970947266,-117.509124755859),(379.146514892578,-98.0416488647461),(386.718719482422,33.8327217102051),(301.160064697266,20.8510036468506),(364.097473144531,76.3949127197266),(331.169189453125,220.886856079102),(265.413391113281,258.454223632812),(230.147384643555,326.805969238281),(159.049774169922,351.167724609375),(74.9347457885742,300.543548583984),(135.337814331055,364.373291015625),(-5.25209617614746,391.923797607422),(-74.5995407104492,376.568267822266),(-127.728973388672,353.416168212891)));
#287=IFCINDEXEDPOLYCURVE(#286,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#288=IFCCARTESIANPOINTLIST3D(((0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(378.284883030077,-2.27555025039633,116.784635922017),(178.595143428464,335.651831866383,124.640558206785),(-183.088878915162,314.752897631551,114.947133794192),(-381.511270028093,-8.00010634603514,128.775855378383),(-172.110176238738,-340.199747584535,125.810867478876),(191.302099550982,-329.414160273537,107.361497258729),(393.598875108319,-1.38140316613422,234.518996106616),(199.179082241675,324.273157299153,237.142238617636),(-178.562776031642,351.03827780132,232.197886828923),(-402.583659748332,-15.8702353869309,216.858549437001),(-179.887927315333,-342.326318683432,224.288087824562),(206.742279825254,-341.958214909756,230.138858459826),(397.952990643972,-13.9201863639408,345.562622079605),(211.010172725181,335.415566902172,334.034709855096),(-202.788153353125,331.591757323652,342.748454812872),(-389.824548338252,5.05251004029154,343.928622398032),(-188.635976295245,-357.620141194691,345.008678116763),(195.973594167939,-343.168416006139,330.470445317765),(396.81640643433,-12.9086133381007,446.466497008241),(203.838392064792,350.344062243514,455.006265224505),(-196.749413384054,327.873276704866,449.933365685756),(-384.247911328827,-10.2892668569367,444.966297281442),(-195.416484522207,-346.739846857814,461.902051741776),(204.273781579568,-327.137492208349,456.507125630036),(371.122280199066,-2.0892624321781,555.588845825671),(194.802342425268,320.238582947285,565.650115036909),(-201.442398962553,323.963341454982,574.07973838219),(-379.501217861028,11.8254574527169,576.975874364524),(-196.274936262054,-324.814228658898,584.565653593263),(188.643510218285,-322.358196023303,557.43732739054),(363.660355728696,-1.2338795905141,682.550441876491),(179.453931460689,317.951168556236,686.951631263826),(-182.32333571869,304.538733074566,683.837383872801),(-349.00229764605,-2.71444181702931,670.844456267496),(-197.909426346164,-314.099856535417,671.332619852593),(168.96778897095,-327.753041773473,684.244792285448),(0.05,0.,800.),(0.025,0.0433012701892219,800.),(-0.025,0.0433012701892219,800.),(-0.05,6.12323399573677E-18,800.),(-0.025,-0.0433012701892219,800.),(0.025,-0.0433012701892219,800.)));
#289=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#290=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#291=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#292=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#293=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#294=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#295=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#296=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#297=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#298=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#299=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#300=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#301=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#302=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#303=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#304=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#305=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#306=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#307=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#308=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#309=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#310=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#311=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#312=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#313=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#314=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#315=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#316=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#317=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#318=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#319=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#320=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#321=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#322=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#323=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#324=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#325=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#326=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#327=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#328=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#329=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#330=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#331=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#332=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#333=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#334=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#335=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#336=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#337=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#338=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#339=IFCPOLYGONALFACESET(#288,$,(#289,#290,#291,#292,#293,#294,#295,#296,#297,#298,#299,#300,#301,#302,#303,#304,#305,#306,#307,#308,#309,#310,#311,#312,#313,#314,#315,#316,#317,#318,#319,#320,#321,#322,#323,#324,#325,#326,#327,#328,#329,#330,#331,#332,#333,#334,#335,#336,#337,#338),$);
#340=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#287));
#341=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#339));
#342=IFCGEOGRAPHICELEMENTTYPE('1esPZTKFXE3Af39$mWJyUW',$,'Hedge Medium (0.8m)',$,$,$,(#347,#352),$,$,.NOTDEFINED.);
#343=IFCCARTESIANPOINT((0.,0.,0.));
#344=IFCDIRECTION((1.,0.,0.));
#345=IFCDIRECTION((0.,0.,1.));
#346=IFCAXIS2PLACEMENT3D(#343,#345,#344);
#347=IFCREPRESENTATIONMAP(#346,#341);
#348=IFCCARTESIANPOINT((0.,0.,0.));
#349=IFCDIRECTION((1.,0.,0.));
#350=IFCDIRECTION((0.,0.,1.));
#351=IFCAXIS2PLACEMENT3D(#348,#350,#349);
#352=IFCREPRESENTATIONMAP(#351,#340);
#353=IFCCARTESIANPOINTLIST2D(((-527.907836914062,778.237060546875),(-682.544250488281,591.5634765625),(-651.098022460938,527.934692382812),(-784.266357421875,419.687042236328),(-828.305480957031,142.130966186523),(-583.854309082031,103.699897766113),(-834.57666015625,81.2796401977539),(-864.603149414062,-256.699737548828),(-725.465026855469,-315.496459960938),(-744.3994140625,-420.946807861328),(-620.988830566406,-602.632385253906),(-559.400024414062,-609.08935546875),(-388.391754150391,-794.232788085938),(-272.846649169922,-812.154357910156),(-289.969635009766,-723.3857421875),(-196.1328125,-857.777404785156),(332.257019042969,-789.601013183594),(277.4853515625,-616.622497558594),(430.038055419922,-728.541809082031),(824.687377929688,-331.956665039062),(744.837707519531,-264.395538330078),(853.079650878906,-220.593704223633),(870.117126464844,76.1236267089844),(677.610168457031,46.9147605895996),(819.219299316406,171.888565063477),(745.130676269531,496.995422363281),(597.18017578125,581.522033691406),(517.831604003906,735.313415527344),(357.861999511719,790.127380371094),(168.603179931641,676.222961425781),(304.510101318359,819.839904785156),(-11.8172159194946,881.828552246094),(-167.848968505859,847.278625488281),(-287.390197753906,795.186340332031)));
#354=IFCINDEXEDPOLYCURVE(#353,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#355=IFCCARTESIANPOINTLIST3D(((0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(851.140986817674,-5.11998806339175,262.765430824539),(401.839072714044,755.216621699362,280.441255965265),(-411.949977559115,708.19401967099,258.631051036932),(-858.400357563209,-18.0002392785791,289.745674601363),(-387.24789653716,-765.449432065204,283.07445182747),(430.429723989709,-741.181860615459,241.563368832141),(885.597468993717,-3.10815712380199,527.667741239885),(448.152935043769,729.614603923094,533.570036889682),(-401.766246071194,789.836125052969,522.445245365077),(-905.813234433747,-35.7080296205946,487.931736233252),(-404.7478364595,-770.234217037722,504.648197605265),(465.170129606822,-769.40598354695,517.812431534608),(895.394228948937,-31.3204193188668,777.515899679111),(474.772888631657,754.685025529888,751.578097173967),(-456.273345044531,746.081453978216,771.184023328963),(-877.105233761067,11.368147590656,773.839400395571),(-424.430946664301,-804.645317688054,776.269525762717),(440.940586877863,-772.128936013813,743.558501964971),(892.836914477244,-29.0443800107266,1004.54961826854),(458.636382145783,788.274140047906,1023.76409675514),(-442.686180114122,737.714872585949,1012.35007279295),(-864.55780048986,-23.1508504281077,1001.17416888324),(-439.687090174966,-780.164655430081,1039.279616419),(459.616008554028,-736.059357468786,1027.14103266758),(835.025130447899,-4.70084047240072,1250.07490310776),(438.305270456854,720.536811631391,1272.71275883304),(-453.245397665745,728.917518273708,1291.67941135993),(-853.877740187312,26.6072792686131,1298.19571732018),(-441.618606589622,-730.832014482521,1315.27272058484),(424.447897991142,-725.305941052431,1254.23398662872),(818.235800389567,-2.77622907865673,1535.7384942221),(403.77134578655,715.390129251532,1545.64117034361),(-410.227505367052,685.212149417774,1538.6341137138),(-785.255169703612,-6.10749408831594,1509.40002660187),(-445.29620927887,-706.724677204688,1510.49839466833),(380.177525184638,-737.444343990313,1539.55078264226),(0.05,0.,1800.),(0.025,0.0433012701892219,1800.),(-0.025,0.0433012701892219,1800.),(-0.05,6.12323399573677E-18,1800.),(-0.025,-0.0433012701892219,1800.),(0.025,-0.0433012701892219,1800.)));
#356=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#357=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#358=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#359=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#360=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#361=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#362=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#363=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#364=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#365=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#366=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#367=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#368=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#369=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#370=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#371=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#372=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#373=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#374=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#375=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#376=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#377=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#378=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#379=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#380=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#381=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#382=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#383=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#384=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#385=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#386=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#387=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#388=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#389=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#390=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#391=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#392=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#393=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#394=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#395=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#396=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#397=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#398=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#399=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#400=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#401=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#402=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#403=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#404=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#405=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#406=IFCPOLYGONALFACESET(#355,$,(#356,#357,#358,#359,#360,#361,#362,#363,#364,#365,#366,#367,#368,#369,#370,#371,#372,#373,#374,#375,#376,#377,#378,#379,#380,#381,#382,#383,#384,#385,#386,#387,#388,#389,#390,#391,#392,#393,#394,#395,#396,#397,#398,#399,#400,#401,#402,#403,#404,#405),$);
#407=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#354));
#408=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#406));
#409=IFCGEOGRAPHICELEMENTTYPE('2ITyucrb9DnxtmPeA_FCBG',$,'Hedge Big (1.8m)',$,$,$,(#414,#419),$,$,.NOTDEFINED.);
#410=IFCCARTESIANPOINT((0.,0.,0.));
#411=IFCDIRECTION((1.,0.,0.));
#412=IFCDIRECTION((0.,0.,1.));
#413=IFCAXIS2PLACEMENT3D(#410,#412,#411);
#414=IFCREPRESENTATIONMAP(#413,#408);
#415=IFCCARTESIANPOINT((0.,0.,0.));
#416=IFCDIRECTION((1.,0.,0.));
#417=IFCDIRECTION((0.,0.,1.));
#418=IFCAXIS2PLACEMENT3D(#415,#417,#416);
#419=IFCREPRESENTATIONMAP(#418,#407);
#420=IFCCARTESIANPOINTLIST3D(((-2517.70166015625,-2646.30053710938,3901.58129882812),(-255.675521850586,-1248.60815429688,5000.),(-1133.70935058594,-349.566070556641,4688.61865234375),(0.,0.,4658.5205078125),(3472.91040039062,-1142.93579101562,3901.58129882812),(1250.74682617188,317.302124023438,5000.),(806.568603515625,-858.251220703125,4688.61865234375),(1171.36364746094,3483.57202148438,3901.58129882812),(-298.783111572266,1267.951171875,5000.),(874.774963378906,818.52783203125,4688.61865234375),(-3164.8310546875,1859.35131835938,3901.58129882812),(-1289.18603515625,-25.3927478790283,5000.),(-613.466796875,1034.14660644531,4688.61865234375)));
#421=IFCINDEXEDPOLYGONALFACE((3,2,1));
#422=IFCINDEXEDPOLYGONALFACE((3,4,2));
#423=IFCINDEXEDPOLYGONALFACE((7,6,5));
#424=IFCINDEXEDPOLYGONALFACE((7,4,6));
#425=IFCINDEXEDPOLYGONALFACE((10,9,8));
#426=IFCINDEXEDPOLYGONALFACE((10,4,9));
#427=IFCINDEXEDPOLYGONALFACE((13,12,11));
#428=IFCINDEXEDPOLYGONALFACE((13,4,12));
#429=IFCPOLYGONALFACESET(#420,$,(#421,#422,#423,#424,#425,#426,#427,#428),$);
#430=IFCCARTESIANPOINT((0.,0.));
#431=IFCAXIS2PLACEMENT2D(#430,$);
#432=IFCCIRCLE(#431,100.);
#433=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#432);
#434=IFCCARTESIANPOINT((0.,0.,0.));
#435=IFCDIRECTION((0.,0.,1.));
#436=IFCDIRECTION((1.,0.,0.));
#437=IFCAXIS2PLACEMENT3D(#434,#435,#436);
#438=IFCDIRECTION((0.,0.,1.));
#439=IFCEXTRUDEDAREASOLID(#433,#437,#438,4658.5204646405);
#440=IFCCARTESIANPOINTLIST2D(((-2517.70166015625,-2646.30053710938,0.),(-255.675521850586,-1248.60815429688,0.),(-1133.70935058594,-349.566070556641,0.),(0.,0.,0.),(3472.91040039062,-1142.93579101562,0.),(1250.74682617188,317.302124023438,0.),(806.568603515625,-858.251220703125,0.),(1171.36364746094,3483.57202148438,0.),(-298.783111572266,1267.951171875,0.),(874.774963378906,818.52783203125,0.),(-3164.8310546875,1859.35131835938,0.),(-1289.18603515625,-25.3927478790283,0.),(-613.466796875,1034.14660644531,0.)));
#441=IFCINDEXEDPOLYCURVE(#440,(IFCLINEINDEX((4,12,11,13,4)),IFCLINEINDEX((4,2,1,3,4)),IFCLINEINDEX((4,6,5,7,4)),IFCLINEINDEX((4,9,8,10,4))),$);
#442=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#441));
#443=IFCSHAPEREPRESENTATION(#15,'Body','SweptSolid',(#429,#439));
#444=IFCGEOGRAPHICELEMENTTYPE('0If5oJIRTAxw5EHjhL6zX$',$,'Palm Tree (5m)',$,$,$,(#449,#454),$,$,.NOTDEFINED.);
#445=IFCCARTESIANPOINT((0.,0.,0.));
#446=IFCDIRECTION((1.,0.,0.));
#447=IFCDIRECTION((0.,0.,1.));
#448=IFCAXIS2PLACEMENT3D(#445,#447,#446);
#449=IFCREPRESENTATIONMAP(#448,#443);
#450=IFCCARTESIANPOINT((0.,0.,0.));
#451=IFCDIRECTION((1.,0.,0.));
#452=IFCDIRECTION((0.,0.,1.));
#453=IFCAXIS2PLACEMENT3D(#450,#452,#451);
#454=IFCREPRESENTATIONMAP(#453,#442);
#455=IFCCARTESIANPOINTLIST3D(((-5223.76025390625,-5490.57861328125,12720.986328125),(-530.478881835938,-2590.62841796875,15000.),(-2352.23486328125,-725.284240722656,14353.9423828125),(0.,0.,14291.4931640625),(7205.64013671875,-2371.37817382812,12720.986328125),(2595.06591796875,658.342590332031,15000.),(1673.47912597656,-1780.7109375,14353.9423828125),(2430.36059570312,7227.76025390625,12720.986328125),(-619.919128417969,2630.76171875,15000.),(1814.99462890625,1698.29223632812,14353.9423828125),(-6566.43310546875,3857.80639648438,12720.986328125),(-2674.81982421875,-52.6852073669434,15000.),(-1272.82897949219,2145.66088867188,14353.9423828125)));
#456=IFCINDEXEDPOLYGONALFACE((3,2,1));
#457=IFCINDEXEDPOLYGONALFACE((3,4,2));
#458=IFCINDEXEDPOLYGONALFACE((7,6,5));
#459=IFCINDEXEDPOLYGONALFACE((7,4,6));
#460=IFCINDEXEDPOLYGONALFACE((10,9,8));
#461=IFCINDEXEDPOLYGONALFACE((10,4,9));
#462=IFCINDEXEDPOLYGONALFACE((13,12,11));
#463=IFCINDEXEDPOLYGONALFACE((13,4,12));
#464=IFCPOLYGONALFACESET(#455,$,(#456,#457,#458,#459,#460,#461,#462,#463),$);
#465=IFCCARTESIANPOINT((0.,0.));
#466=IFCAXIS2PLACEMENT2D(#465,$);
#467=IFCCIRCLE(#466,200.);
#468=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#467);
#469=IFCCARTESIANPOINT((0.,0.,0.));
#470=IFCDIRECTION((0.,0.,1.));
#471=IFCDIRECTION((1.,0.,0.));
#472=IFCAXIS2PLACEMENT3D(#469,#470,#471);
#473=IFCDIRECTION((0.,0.,1.));
#474=IFCEXTRUDEDAREASOLID(#468,#472,#473,14291.4938033876);
#475=IFCCARTESIANPOINTLIST2D(((-5223.76025390625,-5490.57861328125,0.),(-530.478881835938,-2590.62841796875,0.),(-2352.23486328125,-725.284240722656,0.),(0.,0.,0.),(7205.64013671875,-2371.37817382812,0.),(2595.06591796875,658.342590332031,0.),(1673.47912597656,-1780.7109375,0.),(2430.36059570312,7227.76025390625,0.),(-619.919128417969,2630.76171875,0.),(1814.99462890625,1698.29223632812,0.),(-6566.43310546875,3857.80639648438,0.),(-2674.81982421875,-52.6852073669434,0.),(-1272.82897949219,2145.66088867188,0.)));
#476=IFCINDEXEDPOLYCURVE(#475,(IFCLINEINDEX((4,12,11,13,4)),IFCLINEINDEX((4,2,1,3,4)),IFCLINEINDEX((4,6,5,7,4)),IFCLINEINDEX((4,9,8,10,4))),$);
#477=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#476));
#478=IFCSHAPEREPRESENTATION(#15,'Body','SweptSolid',(#464,#474));
#479=IFCGEOGRAPHICELEMENTTYPE('11RlAtH99EAwxYuNeuU3sf',$,'Palm Tree (15m)',$,$,$,(#484,#489),$,$,.NOTDEFINED.);
#480=IFCCARTESIANPOINT((0.,0.,0.));
#481=IFCDIRECTION((1.,0.,0.));
#482=IFCDIRECTION((0.,0.,1.));
#483=IFCAXIS2PLACEMENT3D(#480,#482,#481);
#484=IFCREPRESENTATIONMAP(#483,#478);
#485=IFCCARTESIANPOINT((0.,0.,0.));
#486=IFCDIRECTION((1.,0.,0.));
#487=IFCDIRECTION((0.,0.,1.));
#488=IFCAXIS2PLACEMENT3D(#485,#487,#486);
#489=IFCREPRESENTATIONMAP(#488,#477);
#490=IFCCARTESIANPOINTLIST2D(((-117.312850952148,172.941558837891),(-151.676498413086,131.458541870117),(-144.688446044922,117.318817138672),(-174.28141784668,93.263786315918),(-184.067886352539,31.584659576416),(-129.745407104492,23.0444221496582),(-185.461486816406,18.062141418457),(-192.134033203125,-57.0443878173828),(-161.214447021484,-70.1103286743164),(-165.422088623047,-93.5437316894531),(-137.997512817383,-133.918304443359),(-124.311111450195,-135.353179931641),(-86.3092803955078,-176.496170043945),(-60.6325874328613,-180.478744506836),(-64.4376983642578,-160.752395629883),(-43.5850677490234,-190.617202758789),(73.8348922729492,-175.466888427734),(61.6634140014648,-137.027221679688),(95.5640106201172,-161.898178100586),(183.263854980469,-73.7681503295898),(165.519485473633,-58.7545623779297),(189.573257446289,-49.020824432373),(193.359359741211,16.9163608551025),(150.580032348633,10.4255018234253),(182.048736572266,38.1974563598633),(165.584594726562,110.443428039551),(132.706695556641,129.227111816406),(115.073692321777,163.402984619141),(79.5248870849609,175.583862304688),(37.4673728942871,150.271774291992),(67.6689071655273,182.186645507812),(-2.62604808807373,195.961898803711),(-37.2997703552246,188.284133911133),(-63.8644866943359,176.708084106445)));
#491=IFCINDEXEDPOLYCURVE(#490,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#492=IFCCARTESIANPOINTLIST3D(((0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(117.302441515039,-1.13777512519817,58.3923179610087),(53.377571714232,105.610650925318,62.3202791033923),(-55.6244394575812,95.1611838079015,57.4735668970959),(-118.915635014047,-4.00005317301758,64.3879276891917),(-50.1350881193688,-107.884608784393,62.9054337394378),(59.731049775491,-102.491815128895,53.6807486293646),(146.906104220826,-0.69070158306711,117.259498053308),(74.642874454171,118.927684503425,118.571119308818),(-64.3347213491543,132.310244754508,116.098943414462),(-151.398496540833,-7.93511769346546,108.4292747185),(-64.9972969910001,-127.954265195564,112.144043912281),(78.4244732459604,-127.770213308726,115.069429229913),(171.029828655319,-6.96009318197039,172.781311039802),(91.5317530292571,143.505260166657,167.017354927548),(-87.4207433432292,141.593355377397,171.374227406436),(-166.965607502459,2.52625502014577,171.964311199016),(-80.3446548142891,-154.607547312916,172.504339058381),(84.0134637506361,-147.38168471864,165.235222658882),(204.408203217165,-6.45430666905036,223.233248504121),(104.919196032396,180.368183544464,227.503132612252),(-101.374706692027,169.13279077514,224.966682842878),(-198.123955664413,-5.14463342846837,222.483148640721),(-100.708242261103,-178.566075851614,230.951025870888),(105.136890789784,-168.764898526881,228.253562815018),(169.614473432866,-1.04463121608905,277.794422912835),(89.4278378793009,146.309073034627,282.825057518454),(-92.7478661479432,148.171452288475,287.039869191095),(-173.803942263847,5.91272872635847,288.487937182262),(-90.1641347976938,-148.596895890433,292.282826796631),(86.3484217758093,-147.368879572635,278.71866369527),(143.936844531015,-0.61693979525705,341.275220938245),(70.7802990636777,126.15899497738,343.475815631913),(-72.2150011926783,119.452777236545,341.9186919364),(-136.607815489692,-1.35722090851466,335.422228133748),(-80.0080465064155,-124.23333896697,335.666309926296),(65.5372278188084,-131.059931585998,342.122396142724),(0.05,0.,400.),(0.025,0.0433012701892219,400.),(-0.025,0.0433012701892219,400.),(-0.05,6.12323399573677E-18,400.),(-0.025,-0.0433012701892219,400.),(0.025,-0.0433012701892219,400.)));
#493=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#494=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#495=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#496=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#497=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#498=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#499=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#500=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#501=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#502=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#503=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#504=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#505=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#506=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#507=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#508=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#509=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#510=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#511=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#512=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#513=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#514=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#515=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#516=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#517=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#518=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#519=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#520=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#521=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#522=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#523=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#524=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#525=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#526=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#527=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#528=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#529=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#530=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#531=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#532=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#533=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#534=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#535=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#536=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#537=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#538=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#539=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#540=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#541=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#542=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#543=IFCPOLYGONALFACESET(#492,$,(#493,#494,#495,#496,#497,#498,#499,#500,#501,#502,#503,#504,#505,#506,#507,#508,#509,#510,#511,#512,#513,#514,#515,#516,#517,#518,#519,#520,#521,#522,#523,#524,#525,#526,#527,#528,#529,#530,#531,#532,#533,#534,#535,#536,#537,#538,#539,#540,#541,#542),$);
#544=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#491));
#545=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#543));
#546=IFCGEOGRAPHICELEMENTTYPE('224k6o88949Ak$WjDPqiY0',$,'Shrub Small (0.4m)',$,$,$,(#551,#556),$,$,.NOTDEFINED.);
#547=IFCCARTESIANPOINT((0.,0.,0.));
#548=IFCDIRECTION((1.,0.,0.));
#549=IFCDIRECTION((0.,0.,1.));
#550=IFCAXIS2PLACEMENT3D(#547,#549,#548);
#551=IFCREPRESENTATIONMAP(#550,#545);
#552=IFCCARTESIANPOINT((0.,0.,0.));
#553=IFCDIRECTION((1.,0.,0.));
#554=IFCDIRECTION((0.,0.,1.));
#555=IFCAXIS2PLACEMENT3D(#552,#554,#553);
#556=IFCREPRESENTATIONMAP(#555,#544);
#557=IFCCARTESIANPOINTLIST2D(((-234.625701904297,345.883117675781),(-303.352996826172,262.917083740234),(-289.376892089844,234.637634277344),(-348.562835693359,186.527572631836),(-368.135772705078,63.169319152832),(-259.490814208984,46.0888442993164),(-370.922973632812,36.1242828369141),(-384.26806640625,-114.088775634766),(-322.428894042969,-140.220657348633),(-330.844177246094,-187.087463378906),(-275.995025634766,-267.836608886719),(-248.622222900391,-270.706359863281),(-172.618560791016,-352.992340087891),(-121.265174865723,-360.957489013672),(-128.875396728516,-321.504791259766),(-87.1701354980469,-381.234405517578),(147.669784545898,-350.933776855469),(123.32682800293,-274.054443359375),(191.128021240234,-323.796356201172),(366.527709960938,-147.53630065918),(331.038970947266,-117.509124755859),(379.146514892578,-98.0416488647461),(386.718719482422,33.8327217102051),(301.160064697266,20.8510036468506),(364.097473144531,76.3949127197266),(331.169189453125,220.886856079102),(265.413391113281,258.454223632812),(230.147384643555,326.805969238281),(159.049774169922,351.167724609375),(74.9347457885742,300.543548583984),(135.337814331055,364.373291015625),(-5.25209617614746,391.923797607422),(-74.5995407104492,376.568267822266),(-127.728973388672,353.416168212891)));
#558=IFCINDEXEDPOLYCURVE(#557,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#559=IFCCARTESIANPOINTLIST3D(((0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(234.604883030077,-2.27555025039633,116.784635922017),(106.755143428464,211.221301850635,124.640558206785),(-111.248878915162,190.322367615803,114.947133794192),(-237.831270028093,-8.00010634603516,128.775855378383),(-100.270176238738,-215.769217568787,125.810867478876),(119.462099550982,-204.983630257789,107.361497258729),(293.812208441652,-1.38140316613422,234.518996106616),(149.285748908342,237.85536900685,237.142238617636),(-128.669442698309,264.620489509016,232.197886828923),(-302.796993081665,-15.8702353869309,216.858549437001),(-129.994593982,-255.908530391129,224.288087824562),(156.848946491921,-255.540426617453,230.138858459826),(342.059657310639,-13.9201863639408,345.562622079605),(183.063506058514,287.010520333314,334.034709855096),(-174.841486686458,283.186710754793,342.748454812872),(-333.931215004918,5.05251004029153,343.928622398032),(-160.689309628578,-309.215094625832,345.008678116763),(168.026927501272,-294.763369437281,330.470445317765),(408.81640643433,-12.9086133381007,446.466497008241),(209.838392064792,360.736367088927,455.006265224505),(-202.749413384054,338.26558155028,449.933365685756),(-396.247911328827,-10.2892668569367,444.966297281442),(-201.416484522207,-357.132151703227,461.902051741776),(210.273781579568,-337.529797053763,456.507125630036),(339.228946865733,-2.0892624321781,555.588845825671),(178.855675758602,292.618146069253,565.650115036909),(-185.495732295886,296.34290457695,574.07973838219),(-347.607884527694,11.8254574527169,576.975874364524),(-180.328269595388,-297.193791780866,584.565653593263),(172.696843551619,-294.737759145271,557.43732739054),(287.87368906203,-1.2338795905141,682.550441876491),(141.560598127355,252.31798995476,686.951631263826),(-144.430002385357,238.90555447309,683.837383872801),(-273.215630979383,-2.71444181702932,670.844456267496),(-160.016093012831,-248.46667793394,671.332619852593),(131.074455637617,-262.119863171996,684.244792285448),(0.05,0.,800.),(0.025,0.0433012701892219,800.),(-0.025,0.0433012701892219,800.),(-0.05,6.12323399573677E-18,800.),(-0.025,-0.0433012701892219,800.),(0.025,-0.0433012701892219,800.)));
#560=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#561=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#562=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#563=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#564=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#565=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#566=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#567=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#568=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#569=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#570=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#571=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#572=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#573=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#574=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#575=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#576=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#577=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#578=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#579=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#580=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#581=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#582=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#583=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#584=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#585=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#586=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#587=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#588=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#589=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#590=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#591=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#592=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#593=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#594=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#595=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#596=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#597=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#598=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#599=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#600=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#601=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#602=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#603=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#604=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#605=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#606=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#607=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#608=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#609=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#610=IFCPOLYGONALFACESET(#559,$,(#560,#561,#562,#563,#564,#565,#566,#567,#568,#569,#570,#571,#572,#573,#574,#575,#576,#577,#578,#579,#580,#581,#582,#583,#584,#585,#586,#587,#588,#589,#590,#591,#592,#593,#594,#595,#596,#597,#598,#599,#600,#601,#602,#603,#604,#605,#606,#607,#608,#609),$);
#611=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#558));
#612=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#610));
#613=IFCGEOGRAPHICELEMENTTYPE('0sCZ5iWS904ODo2Mqo8nHu',$,'Shrum Medium (0.8m)',$,$,$,(#618,#623),$,$,.NOTDEFINED.);
#614=IFCCARTESIANPOINT((0.,0.,0.));
#615=IFCDIRECTION((1.,0.,0.));
#616=IFCDIRECTION((0.,0.,1.));
#617=IFCAXIS2PLACEMENT3D(#614,#616,#615);
#618=IFCREPRESENTATIONMAP(#617,#612);
#619=IFCCARTESIANPOINT((0.,0.,0.));
#620=IFCDIRECTION((1.,0.,0.));
#621=IFCDIRECTION((0.,0.,1.));
#622=IFCAXIS2PLACEMENT3D(#619,#621,#620);
#623=IFCREPRESENTATIONMAP(#622,#611);
#624=IFCCARTESIANPOINTLIST2D(((-527.907836914062,778.237060546875),(-682.544250488281,591.5634765625),(-651.098022460938,527.934692382812),(-784.266357421875,419.687042236328),(-828.305480957031,142.130966186523),(-583.854309082031,103.699897766113),(-834.57666015625,81.2796401977539),(-864.603149414062,-256.699737548828),(-725.465026855469,-315.496459960938),(-744.3994140625,-420.946807861328),(-620.988830566406,-602.632385253906),(-559.400024414062,-609.08935546875),(-388.391754150391,-794.232788085938),(-272.846649169922,-812.154357910156),(-289.969635009766,-723.3857421875),(-196.1328125,-857.777404785156),(332.257019042969,-789.601013183594),(277.4853515625,-616.622497558594),(430.038055419922,-728.541809082031),(824.687377929688,-331.956665039062),(744.837707519531,-264.395538330078),(853.079650878906,-220.593704223633),(870.117126464844,76.1236267089844),(677.610168457031,46.9147605895996),(819.219299316406,171.888565063477),(745.130676269531,496.995422363281),(597.18017578125,581.522033691406),(517.831604003906,735.313415527344),(357.861999511719,790.127380371094),(168.603179931641,676.222961425781),(304.510101318359,819.839904785156),(-11.8172159194946,881.828552246094),(-167.848968505859,847.278625488281),(-287.390197753906,795.186340332031)));
#625=IFCINDEXEDPOLYCURVE(#624,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#626=IFCCARTESIANPOINTLIST3D(((0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(0.,0.,0.),(527.860986817674,-5.11998806339175,262.765430824539),(240.199072714044,475.247929163929,280.441255965265),(-250.309977559115,428.225327135557,258.631051036932),(-535.120357563209,-18.0002392785791,289.745674601363),(-225.607896537159,-485.480739529771,283.07445182747),(268.789723989709,-461.213168080025,241.563368832141),(661.077468993717,-3.10815712380199,527.667741239885),(335.892935043769,535.174580265412,533.570036889682),(-289.506246071194,595.396101395287,522.445245365077),(-681.293234433747,-35.7080296205946,487.931736233252),(-292.4878364595,-575.794193380039,504.648197605265),(352.910129606822,-574.965959889268,517.812431534608),(769.634228948937,-31.3204193188668,777.515899679111),(411.892888631657,645.773670749957,751.578097173967),(-393.393345044531,637.170099198285,771.184023328963),(-751.345233761067,11.3681475906559,773.839400395571),(-361.550946664301,-695.733962908123,776.269525762717),(378.060586877863,-663.217581233882,743.558501964971),(919.836914477244,-29.0443800107266,1004.54961826854),(472.136382145783,811.656825950086,1023.76409675514),(-456.186180114122,761.097558488129,1012.35007279295),(-891.55780048986,-23.1508504281077,1001.17416888324),(-453.187090174966,-803.547341332261,1039.279616419),(473.116008554028,-759.442043370966,1027.14103266758),(763.265130447899,-4.70084047240072,1250.07490310776),(402.425270456854,658.39082865582,1272.71275883304),(-417.365397665745,666.771535298137,1291.67941135993),(-782.117740187312,26.6072792686131,1298.19571732018),(-405.738606589622,-668.686031506949,1315.27272058484),(388.567897991142,-663.159958076859,1254.23398662872),(647.715800389567,-2.77622907865673,1535.7384942221),(318.51134578655,567.715477398209,1545.64117034361),(-324.967505367052,537.537497564452,1538.6341137138),(-614.735169703612,-6.10749408831597,1509.40002660187),(-360.03620927887,-559.050025351365,1510.49839466833),(294.917525184638,-589.769692136991,1539.55078264226),(0.05,0.,1800.),(0.025,0.0433012701892219,1800.),(-0.025,0.0433012701892219,1800.),(-0.05,6.12323399573677E-18,1800.),(-0.025,-0.0433012701892219,1800.),(0.025,-0.0433012701892219,1800.)));
#627=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#628=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#629=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#630=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#631=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#632=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#633=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#634=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#635=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#636=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#637=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#638=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#639=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#640=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#641=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#642=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#643=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#644=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#645=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#646=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#647=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#648=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#649=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#650=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#651=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#652=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#653=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#654=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#655=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#656=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#657=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#658=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#659=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#660=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#661=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#662=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#663=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#664=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#665=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#666=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#667=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#668=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#669=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#670=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#671=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#672=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#673=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#674=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#675=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#676=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#677=IFCPOLYGONALFACESET(#626,$,(#627,#628,#629,#630,#631,#632,#633,#634,#635,#636,#637,#638,#639,#640,#641,#642,#643,#644,#645,#646,#647,#648,#649,#650,#651,#652,#653,#654,#655,#656,#657,#658,#659,#660,#661,#662,#663,#664,#665,#666,#667,#668,#669,#670,#671,#672,#673,#674,#675,#676),$);
#678=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#625));
#679=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#677));
#680=IFCGEOGRAPHICELEMENTTYPE('3mKZtHjt12Rh_uInKdrcGZ',$,'Shrub Big (1.8m)',$,$,$,(#685,#690),$,$,.NOTDEFINED.);
#681=IFCCARTESIANPOINT((0.,0.,0.));
#682=IFCDIRECTION((1.,0.,0.));
#683=IFCDIRECTION((0.,0.,1.));
#684=IFCAXIS2PLACEMENT3D(#681,#683,#682);
#685=IFCREPRESENTATIONMAP(#684,#679);
#686=IFCCARTESIANPOINT((0.,0.,0.));
#687=IFCDIRECTION((1.,0.,0.));
#688=IFCDIRECTION((0.,0.,1.));
#689=IFCAXIS2PLACEMENT3D(#686,#688,#687);
#690=IFCREPRESENTATIONMAP(#689,#678);
#691=IFCCARTESIANPOINT((0.,0.));
#692=IFCAXIS2PLACEMENT2D(#691,$);
#693=IFCCIRCLE(#692,100.);
#694=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#693);
#695=IFCCARTESIANPOINT((0.,0.,0.));
#696=IFCDIRECTION((0.,0.,1.));
#697=IFCDIRECTION((1.,0.,0.));
#698=IFCAXIS2PLACEMENT3D(#695,#696,#697);
#699=IFCDIRECTION((0.,0.,1.));
#700=IFCEXTRUDEDAREASOLID(#694,#698,#699,460.);
#701=IFCCARTESIANPOINT((0.,0.,1130.));
#702=IFCDIRECTION((0.,0.,1.));
#703=IFCDIRECTION((1.,0.,0.));
#704=IFCAXIS2PLACEMENT3D(#701,#702,#703);
#705=IFCSPHERE(#704,670.);
#706=IFCCARTESIANPOINT((0.,0.));
#707=IFCAXIS2PLACEMENT2D(#706,$);
#708=IFCCIRCLE(#707,670.);
#709=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#708));
#710=IFCSHAPEREPRESENTATION(#15,'Body','SweptSolid',(#700,#705));
#711=IFCGEOGRAPHICELEMENTTYPE('24b7xpbZb38f1BXogqUXhD',$,'Simple Tree (1.8m)',$,$,$,(#716,#721),$,$,.NOTDEFINED.);
#712=IFCCARTESIANPOINT((0.,0.,0.));
#713=IFCDIRECTION((1.,0.,0.));
#714=IFCDIRECTION((0.,0.,1.));
#715=IFCAXIS2PLACEMENT3D(#712,#714,#713);
#716=IFCREPRESENTATIONMAP(#715,#710);
#717=IFCCARTESIANPOINT((0.,0.,0.));
#718=IFCDIRECTION((1.,0.,0.));
#719=IFCDIRECTION((0.,0.,1.));
#720=IFCAXIS2PLACEMENT3D(#717,#719,#718);
#721=IFCREPRESENTATIONMAP(#720,#709);
#722=IFCCARTESIANPOINT((0.,0.));
#723=IFCAXIS2PLACEMENT2D(#722,$);
#724=IFCCIRCLE(#723,100.);
#725=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#724);
#726=IFCCARTESIANPOINT((0.,0.,0.));
#727=IFCDIRECTION((0.,0.,1.));
#728=IFCDIRECTION((1.,0.,0.));
#729=IFCAXIS2PLACEMENT3D(#726,#727,#728);
#730=IFCDIRECTION((0.,0.,1.));
#731=IFCEXTRUDEDAREASOLID(#725,#729,#730,1710.);
#732=IFCCARTESIANPOINT((0.,0.,3355.));
#733=IFCDIRECTION((0.,0.,1.));
#734=IFCDIRECTION((1.,0.,0.));
#735=IFCAXIS2PLACEMENT3D(#732,#733,#734);
#736=IFCSPHERE(#735,1645.);
#737=IFCCARTESIANPOINT((0.,0.));
#738=IFCAXIS2PLACEMENT2D(#737,$);
#739=IFCCIRCLE(#738,1645.);
#740=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#739));
#741=IFCSHAPEREPRESENTATION(#15,'Body','SweptSolid',(#731,#736));
#742=IFCGEOGRAPHICELEMENTTYPE('3VL8Zl9Xb2AwPSDD7jujfl',$,'Simple Tree (5m)',$,$,$,(#747,#752),$,$,.NOTDEFINED.);
#743=IFCCARTESIANPOINT((0.,0.,0.));
#744=IFCDIRECTION((1.,0.,0.));
#745=IFCDIRECTION((0.,0.,1.));
#746=IFCAXIS2PLACEMENT3D(#743,#745,#744);
#747=IFCREPRESENTATIONMAP(#746,#741);
#748=IFCCARTESIANPOINT((0.,0.,0.));
#749=IFCDIRECTION((1.,0.,0.));
#750=IFCDIRECTION((0.,0.,1.));
#751=IFCAXIS2PLACEMENT3D(#748,#750,#749);
#752=IFCREPRESENTATIONMAP(#751,#740);
#753=IFCCARTESIANPOINT((0.,0.));
#754=IFCAXIS2PLACEMENT2D(#753,$);
#755=IFCCIRCLE(#754,220.);
#756=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#755);
#757=IFCCARTESIANPOINT((0.,0.,0.));
#758=IFCDIRECTION((0.,0.,1.));
#759=IFCDIRECTION((1.,0.,0.));
#760=IFCAXIS2PLACEMENT3D(#757,#758,#759);
#761=IFCDIRECTION((0.,0.,1.));
#762=IFCEXTRUDEDAREASOLID(#756,#760,#761,5790.);
#763=IFCCARTESIANPOINT((0.,0.,10395.));
#764=IFCDIRECTION((0.,0.,1.));
#765=IFCDIRECTION((1.,0.,0.));
#766=IFCAXIS2PLACEMENT3D(#763,#764,#765);
#767=IFCSPHERE(#766,4605.);
#768=IFCCARTESIANPOINT((0.,0.));
#769=IFCAXIS2PLACEMENT2D(#768,$);
#770=IFCCIRCLE(#769,4605.);
#771=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#770));
#772=IFCSHAPEREPRESENTATION(#15,'Body','SweptSolid',(#762,#767));
#773=IFCGEOGRAPHICELEMENTTYPE('3jGYIuJcL0phM2h4r9r95Q',$,'Simple Tree (15m)',$,$,$,(#778,#783),$,$,.NOTDEFINED.);
#774=IFCCARTESIANPOINT((0.,0.,0.));
#775=IFCDIRECTION((1.,0.,0.));
#776=IFCDIRECTION((0.,0.,1.));
#777=IFCAXIS2PLACEMENT3D(#774,#776,#775);
#778=IFCREPRESENTATIONMAP(#777,#772);
#779=IFCCARTESIANPOINT((0.,0.,0.));
#780=IFCDIRECTION((1.,0.,0.));
#781=IFCDIRECTION((0.,0.,1.));
#782=IFCAXIS2PLACEMENT3D(#779,#781,#780);
#783=IFCREPRESENTATIONMAP(#782,#771);
#784=IFCCARTESIANPOINTLIST2D(((-498.579620361328,735.001647949219),(-644.625122070312,558.698791503906),(-614.925903320312,498.60498046875),(-740.696044921875,396.37109375),(-782.288513183594,134.234802246094),(-551.41796875,97.9387969970703),(-788.211303710938,76.7640991210938),(-816.569641113281,-242.43864440918),(-685.161376953125,-297.968902587891),(-703.043884277344,-397.560852050781),(-586.489440917969,-569.15283203125),(-528.322204589844,-575.251037597656),(-366.814422607422,-750.108703613281),(-257.688507080078,-767.03466796875),(-273.860229492188,-683.197692871094),(-185.236541748047,-810.123107910156),(313.798278808594,-745.734313964844),(262.069519042969,-582.365661621094),(406.147064208984,-688.067260742188),(778.871398925781,-313.5146484375),(703.457824707031,-249.706893920898),(805.686340332031,-208.338500976562),(821.777282714844,71.8945388793945),(639.965148925781,44.3083839416504),(773.707153320312,162.339202880859),(703.734558105469,469.384552001953),(564.003479003906,549.215209960938),(489.063201904297,694.462707519531),(337.980773925781,746.2314453125),(159.236328125,638.655029296875),(287.592864990234,774.293273925781),(-11.1607036590576,832.838073730469),(-158.524017333984,800.207580566406),(-271.424072265625,751.009338378906)));
#785=IFCINDEXEDPOLYCURVE(#784,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#786=IFCCARTESIANPOINTLIST3D(((80.,0.,0.),(40.,69.2820323027551,0.),(-40.,69.2820323027551,0.),(-80.,9.79717439317883E-15,0.),(-40.,-69.2820323027551,0.),(40.,-69.2820323027551,0.),(80.,0.,280.),(40.,69.2820323027551,280.),(-40.,69.2820323027551,280.),(-80.,9.79717439317883E-15,280.),(-40.,-69.2820323027551,280.),(40.,-69.2820323027551,280.),(610.340986817674,-5.11998806339175,502.765430824539),(281.439072714044,546.677704468069,520.441255965265),(-291.549977559115,499.655102439697,498.631051036932),(-617.600357563209,-18.0002392785791,529.745674601363),(-266.847896537159,-556.910514833911,523.07445182747),(310.029723989709,-532.642943384166,481.563368832141),(699.397468993717,-3.10815712380199,727.667741239885),(355.052935043769,568.360673738432,733.570036889682),(-308.666246071194,628.582194868307,722.445245365077),(-719.613234433747,-35.7080296205946,687.931736233252),(-311.6478364595,-608.980286853059,704.648197605265),(372.070129606822,-608.152053362288,717.812431534607),(763.794228948937,-31.3204193188668,937.51589967911),(408.972888631657,640.716082391856,911.578097173966),(-390.473345044531,632.112510840184,931.184023328963),(-745.505233761067,11.3681475906559,933.839400395571),(-358.630946664301,-690.676374550022,936.269525762716),(375.140586877863,-658.159992875781,903.558501964971),(869.836914477244,-29.0443800107266,1124.54961826854),(447.136382145783,768.355555760864,1143.76409675514),(-431.186180114122,717.796288298907,1132.35007279295),(-841.55780048986,-23.1508504281077,1121.17416888324),(-428.187090174966,-760.246071143039,1159.279616419),(448.116008554028,-716.140773181744,1147.14103266758),(757.425130447899,-4.70084047240072,1330.07490310776),(399.505270456854,653.333240297718,1352.71275883304),(-414.445397665745,661.713946940036,1371.67941135993),(-776.277740187312,26.6072792686131,1378.19571732018),(-402.818606589622,-663.628443148848,1395.27272058484),(385.647897991142,-658.102369718758,1334.23398662872),(686.035800389567,-2.77622907865673,1575.7384942221),(337.67134578655,600.901570871229,1585.64117034361),(-344.127505367052,570.723591037471,1578.6341137138),(-653.055169703612,-6.10749408831596,1549.40002660187),(-379.19620927887,-592.236118824385,1550.49839466833),(314.077525184638,-622.955785610011,1579.55078264226),(0.05,0.,1800.),(0.025,0.0433012701892219,1800.),(-0.025,0.0433012701892219,1800.),(-0.05,6.12323399573677E-18,1800.),(-0.025,-0.0433012701892219,1800.),(0.025,-0.0433012701892219,1800.)));
#787=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#788=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#789=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#790=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#791=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#792=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#793=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#794=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#795=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#796=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#797=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#798=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#799=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#800=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#801=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#802=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#803=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#804=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#805=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#806=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#807=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#808=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#809=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#810=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#811=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#812=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#813=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#814=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#815=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#816=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#817=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#818=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#819=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#820=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#821=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#822=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#823=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#824=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#825=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#826=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#827=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#828=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#829=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#830=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#831=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#832=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#833=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#834=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#835=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#836=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#837=IFCPOLYGONALFACESET(#786,$,(#787,#788,#789,#790,#791,#792,#793,#794,#795,#796,#797,#798,#799,#800,#801,#802,#803,#804,#805,#806,#807,#808,#809,#810,#811,#812,#813,#814,#815,#816,#817,#818,#819,#820,#821,#822,#823,#824,#825,#826,#827,#828,#829,#830,#831,#832,#833,#834,#835,#836),$);
#838=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#785));
#839=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#837));
#840=IFCGEOGRAPHICELEMENTTYPE('1CLHhCfcnFaBY1EM4kLSOR',$,'Tree Small (1.8m)',$,$,$,(#845,#850),$,$,.NOTDEFINED.);
#841=IFCCARTESIANPOINT((0.,0.,0.));
#842=IFCDIRECTION((1.,0.,0.));
#843=IFCDIRECTION((0.,0.,1.));
#844=IFCAXIS2PLACEMENT3D(#841,#843,#842);
#845=IFCREPRESENTATIONMAP(#844,#839);
#846=IFCCARTESIANPOINT((0.,0.,0.));
#847=IFCDIRECTION((1.,0.,0.));
#848=IFCDIRECTION((0.,0.,1.));
#849=IFCAXIS2PLACEMENT3D(#846,#848,#847);
#850=IFCREPRESENTATIONMAP(#849,#838);
#851=IFCCARTESIANPOINTLIST2D(((-2932.8212890625,4323.5390625),(-3791.91259765625,3286.46362304688),(-3617.21118164062,2932.97045898438),(-4357.03564453125,2331.5947265625),(-4601.697265625,789.616455078125),(-3243.63500976562,576.110534667969),(-4636.537109375,451.553527832031),(-4803.35107421875,-1426.10961914062),(-4030.36108398438,-1752.75817871094),(-4135.55224609375,-2338.59326171875),(-3449.93798828125,-3347.95776367188),(-3107.77783203125,-3383.82958984375),(-2157.73193359375,-4412.404296875),(-1515.81469726562,-4511.96826171875),(-1610.94250488281,-4018.80981445312),(-1089.62670898438,-4765.43017578125),(1845.87219238281,-4386.67236328125),(1541.58532714844,-3425.68041992188),(2389.10034179688,-4047.45458984375),(4581.5966796875,-1844.20373535156),(4137.9873046875,-1468.86413574219),(4739.33154296875,-1225.52062988281),(4833.98388671875,422.909027099609),(3764.5009765625,260.637542724609),(4551.21826171875,954.936462402344),(4139.615234375,2761.08569335938),(3317.66748046875,3230.677734375),(2876.84228515625,4085.07470703125),(1988.12219238281,4389.5966796875),(936.684326171875,3756.79443359375),(1691.72277832031,4554.66650390625),(-65.6511993408203,4899.0478515625),(-932.494262695312,4707.103515625),(-1596.61218261719,4417.7021484375)));
#852=IFCINDEXEDPOLYCURVE(#851,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#853=IFCCARTESIANPOINTLIST3D(((220.,0.,0.),(110.,190.525588832576,0.),(-110.,190.525588832577,0.),(-220.,2.69422295812418E-14,0.),(-110.,-190.525588832576,0.),(110.,-190.525588832576,0.),(220.,0.,1830.),(110.,190.525588832576,1830.),(-110.,190.525588832577,1830.),(-220.,2.69422295812418E-14,1830.),(-110.,-190.525588832576,1830.),(110.,-190.525588832576,1830.),(3602.84155681395,-42.6665671949312,3758.28335210925),(1603.6589392837,3271.04318828699,3905.58189494864),(-1687.91647965929,2879.18817138389,3723.83018721253),(-3663.33631302674,-150.001993988159,3983.11871691612),(-1482.06580447633,-3356.31660800234,3927.52519380035),(1841.91436658091,-3154.08684592113,3581.5995021726),(4144.97890828097,-25.9013093650166,5704.3740341419),(2117.10779203141,3278.52951811646,5753.55983122354),(-1730.55205059328,3780.37552753208,5660.85323518517),(-4313.44362028123,-297.566913504955,5373.24065908662),(-1755.3986371625,-3617.02629407169,5512.5445038534),(2258.91774672351,-3610.12434831526,5622.24645326459),(4481.61857457447,-261.00349432389,7525.01344970687),(2466.44073859714,3708.28617613811,7308.86509549734),(-2312.27787537109,3636.58974654084,7472.24781345564),(-4329.21028134222,94.734563255466,7494.37595567738),(-2046.92455553584,-4124.62194412282,7514.62700040359),(2184.50489064885,-3853.65209683748,7242.03513542238),(5165.3076206437,-242.036500089388,9155.53253319023),(2684.46985121485,4598.74337345629,9315.65318724518),(-2551.55150095102,4177.41614460665,9220.53632089363),(-4929.6483374155,-192.923753567564,9127.40378831275),(-2526.55908479138,-4531.16433497441,9444.94918444402),(2692.6334046169,-4163.62018529695,9343.7943198489),(4428.54275373249,-39.1736706033394,10940.1480020885),(2387.54392047378,3813.42915868696,11128.7967997992),(-2512.04498054787,3883.26838070627,11286.8522375232),(-4585.64783489427,221.727327238442,11341.154787192),(-2415.15505491352,-3899.22251577971,11483.4631477308),(2272.06581659285,-3853.17190386229,10974.8070314298),(4033.63166991306,-23.1352423221394,13059.2493566128),(1972.26121488791,3549.70366088977,13141.7716576253),(-2026.06254472544,3298.22049560846,13083.3795190436),(-3758.79308086343,-50.8957840692999,12839.7621264441),(-2318.30174399058,-3477.4915604994,12848.9151936647),(1775.64604320532,-3733.48878371295,13091.0184267807),(0.05,0.,15000.),(0.025,0.0433012701892219,15000.),(-0.025,0.0433012701892219,15000.),(-0.05,6.12323399573677E-18,15000.),(-0.025,-0.0433012701892219,15000.),(0.025,-0.0433012701892219,15000.)));
#854=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#855=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#856=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#857=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#858=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#859=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#860=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#861=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#862=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#863=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#864=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#865=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#866=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#867=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#868=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#869=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#870=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#871=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#872=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#873=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#874=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#875=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#876=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#877=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#878=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#879=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#880=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#881=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#882=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#883=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#884=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#885=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#886=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#887=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#888=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#889=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#890=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#891=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#892=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#893=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#894=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#895=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#896=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#897=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#898=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#899=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#900=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#901=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#902=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#903=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#904=IFCPOLYGONALFACESET(#853,$,(#854,#855,#856,#857,#858,#859,#860,#861,#862,#863,#864,#865,#866,#867,#868,#869,#870,#871,#872,#873,#874,#875,#876,#877,#878,#879,#880,#881,#882,#883,#884,#885,#886,#887,#888,#889,#890,#891,#892,#893,#894,#895,#896,#897,#898,#899,#900,#901,#902,#903),$);
#905=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#852));
#906=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#904));
#907=IFCGEOGRAPHICELEMENTTYPE('1$Hd6qXnz8ff4y_T2Agko8',$,'Tree Big (15m)',$,$,$,(#912,#917),$,$,.NOTDEFINED.);
#908=IFCCARTESIANPOINT((0.,0.,0.));
#909=IFCDIRECTION((1.,0.,0.));
#910=IFCDIRECTION((0.,0.,1.));
#911=IFCAXIS2PLACEMENT3D(#908,#910,#909);
#912=IFCREPRESENTATIONMAP(#911,#906);
#913=IFCCARTESIANPOINT((0.,0.,0.));
#914=IFCDIRECTION((1.,0.,0.));
#915=IFCDIRECTION((0.,0.,1.));
#916=IFCAXIS2PLACEMENT3D(#913,#915,#914);
#917=IFCREPRESENTATIONMAP(#916,#905);
#918=IFCCARTESIANPOINTLIST2D(((-1466.41064453125,2161.76953125),(-1895.95629882812,1643.23181152344),(-1808.60559082031,1466.48522949219),(-2178.51782226562,1165.79736328125),(-2300.8486328125,394.808227539062),(-1621.81750488281,288.055267333984),(-2318.2685546875,225.776763916016),(-2401.67553710938,-713.054809570312),(-2015.18054199219,-876.379089355469),(-2067.77612304688,-1169.29663085938),(-1724.96899414062,-1673.97888183594),(-1553.88891601562,-1691.91479492188),(-1078.86596679688,-2206.2021484375),(-757.907348632812,-2255.98413085938),(-805.471252441406,-2009.40490722656),(-544.813354492188,-2382.71508789062),(922.936096191406,-2193.33618164062),(770.792663574219,-1712.84020996094),(1194.55017089844,-2023.72729492188),(2290.79833984375,-922.101867675781),(2068.99365234375,-734.432067871094),(2369.66577148438,-612.760314941406),(2416.99194335938,211.454513549805),(1882.25048828125,130.318771362305),(2275.60913085938,477.468231201172),(2069.8076171875,1380.54284667969),(1658.83374023438,1615.3388671875),(1438.42114257812,2042.53735351562),(994.061096191406,2194.79833984375),(468.342163085938,1878.39721679688),(845.861389160156,2277.33325195312),(-32.8255996704102,2449.52392578125),(-466.247131347656,2353.5517578125),(-798.306091308594,2208.85107421875)));
#919=IFCINDEXEDPOLYCURVE(#918,(IFCLINEINDEX((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1))),$);
#920=IFCCARTESIANPOINTLIST3D(((110.,0.,0.),(55.,95.2627944162882,0.),(-55.,95.2627944162883,0.),(-110.,1.34711147906209E-14,0.),(-55.,-95.2627944162882,0.),(55.,-95.2627944162882,0.),(110.,0.,840.),(55.,95.2627944162882,840.),(-55.,95.2627944162883,840.),(-110.,1.34711147906209E-14,840.),(-55.,-95.2627944162882,840.),(55.,-95.2627944162882,840.),(1794.28051893798,-14.2221890649771,1449.90397451261),(831.219646427901,1604.18946900776,1499.0034887924),(-859.305493219764,1473.57113004006,1438.4195862137),(-1814.44543767558,-50.0006646627197,1524.8490961149),(-790.68860149211,-1632.61394224621,1506.31792174297),(910.638122193637,-1565.20402155248,1391.00935786706),(2054.99296942699,-8.63376978833887,2065.74372566635),(1042.36926401047,1675.96694458701,2082.13899136023),(-913.517350197761,1843.24894772555,2051.23679268077),(-2111.14787342708,-99.1889711683183,1955.36593398126),(-921.799545720834,-1788.79920323875,2001.80054890351),(1089.63924890784,-1786.49855465328,2038.36786537391),(2247.20619152482,-87.0011647746299,2639.76638799753),(1198.81357953238,1888.50119623031,2567.71693659435),(-1147.42595845703,1864.60238636456,2622.17784258045),(-2196.40342711407,31.5781877518221,2629.5538899877),(-1058.97485184528,-2027.27978555855,2636.30423822977),(1104.83496354962,-1936.9565031301,2545.44028323603),(2555.10254021457,-80.6788333631295,3150.41560630151),(1311.48995040495,2254.60229430579,3203.78915765315),(-1267.18383365034,2114.15988468925,3172.08353553597),(-2476.54944580517,-64.3079178558546,3141.03935800901),(-1258.85302826379,-2232.07594814517,3246.8878233861),(1314.2111348723,-2109.56123158602,3213.16953518773),(2229.51425124416,-13.0578902011131,3712.43028641044),(1172.51464015793,1923.54885707993,3775.31321898068),(-1214.01499351596,1946.82859775303,3827.99836488869),(-2281.88261163142,73.9091090794808,3846.09921477827),(-1181.71835163784,-1952.14664277751,3893.53533495789),(1134.02193886428,-1936.79643880504,3723.98329619088),(2017.87722330435,-7.71174744071313,4385.94026172807),(994.087071629305,1766.35832551144,4413.44769539892),(-1012.02084824181,1682.53060375101,4393.983649205),(-1926.26436028781,-16.9652613564332,4312.77785167185),(-1109.43391466353,-1742.28762538132,4315.82887407871),(928.548681068438,-1827.62003311917,4396.52995178405),(0.05,0.,5000.),(0.025,0.0433012701892219,5000.),(-0.025,0.0433012701892219,5000.),(-0.05,6.12323399573677E-18,5000.),(-0.025,-0.0433012701892219,5000.),(0.025,-0.0433012701892219,5000.)));
#921=IFCINDEXEDPOLYGONALFACE((1,2,3,4,5,6));
#922=IFCINDEXEDPOLYGONALFACE((6,1,7,12));
#923=IFCINDEXEDPOLYGONALFACE((1,2,8,7));
#924=IFCINDEXEDPOLYGONALFACE((2,3,9,8));
#925=IFCINDEXEDPOLYGONALFACE((3,4,10,9));
#926=IFCINDEXEDPOLYGONALFACE((4,5,11,10));
#927=IFCINDEXEDPOLYGONALFACE((5,6,12,11));
#928=IFCINDEXEDPOLYGONALFACE((12,7,13,18));
#929=IFCINDEXEDPOLYGONALFACE((7,8,14,13));
#930=IFCINDEXEDPOLYGONALFACE((8,9,15,14));
#931=IFCINDEXEDPOLYGONALFACE((9,10,16,15));
#932=IFCINDEXEDPOLYGONALFACE((10,11,17,16));
#933=IFCINDEXEDPOLYGONALFACE((11,12,18,17));
#934=IFCINDEXEDPOLYGONALFACE((18,13,19,24));
#935=IFCINDEXEDPOLYGONALFACE((13,14,20,19));
#936=IFCINDEXEDPOLYGONALFACE((14,15,21,20));
#937=IFCINDEXEDPOLYGONALFACE((15,16,22,21));
#938=IFCINDEXEDPOLYGONALFACE((16,17,23,22));
#939=IFCINDEXEDPOLYGONALFACE((17,18,24,23));
#940=IFCINDEXEDPOLYGONALFACE((24,19,25,30));
#941=IFCINDEXEDPOLYGONALFACE((19,20,26,25));
#942=IFCINDEXEDPOLYGONALFACE((20,21,27,26));
#943=IFCINDEXEDPOLYGONALFACE((21,22,28,27));
#944=IFCINDEXEDPOLYGONALFACE((22,23,29,28));
#945=IFCINDEXEDPOLYGONALFACE((23,24,30,29));
#946=IFCINDEXEDPOLYGONALFACE((30,25,31,36));
#947=IFCINDEXEDPOLYGONALFACE((25,26,32,31));
#948=IFCINDEXEDPOLYGONALFACE((26,27,33,32));
#949=IFCINDEXEDPOLYGONALFACE((27,28,34,33));
#950=IFCINDEXEDPOLYGONALFACE((28,29,35,34));
#951=IFCINDEXEDPOLYGONALFACE((29,30,36,35));
#952=IFCINDEXEDPOLYGONALFACE((36,31,37,42));
#953=IFCINDEXEDPOLYGONALFACE((31,32,38,37));
#954=IFCINDEXEDPOLYGONALFACE((32,33,39,38));
#955=IFCINDEXEDPOLYGONALFACE((33,34,40,39));
#956=IFCINDEXEDPOLYGONALFACE((34,35,41,40));
#957=IFCINDEXEDPOLYGONALFACE((35,36,42,41));
#958=IFCINDEXEDPOLYGONALFACE((42,37,43,48));
#959=IFCINDEXEDPOLYGONALFACE((37,38,44,43));
#960=IFCINDEXEDPOLYGONALFACE((38,39,45,44));
#961=IFCINDEXEDPOLYGONALFACE((39,40,46,45));
#962=IFCINDEXEDPOLYGONALFACE((40,41,47,46));
#963=IFCINDEXEDPOLYGONALFACE((41,42,48,47));
#964=IFCINDEXEDPOLYGONALFACE((48,43,49,54));
#965=IFCINDEXEDPOLYGONALFACE((43,44,50,49));
#966=IFCINDEXEDPOLYGONALFACE((44,45,51,50));
#967=IFCINDEXEDPOLYGONALFACE((45,46,52,51));
#968=IFCINDEXEDPOLYGONALFACE((46,47,53,52));
#969=IFCINDEXEDPOLYGONALFACE((47,48,54,53));
#970=IFCINDEXEDPOLYGONALFACE((49,50,51,52,53,54));
#971=IFCPOLYGONALFACESET(#920,$,(#921,#922,#923,#924,#925,#926,#927,#928,#929,#930,#931,#932,#933,#934,#935,#936,#937,#938,#939,#940,#941,#942,#943,#944,#945,#946,#947,#948,#949,#950,#951,#952,#953,#954,#955,#956,#957,#958,#959,#960,#961,#962,#963,#964,#965,#966,#967,#968,#969,#970),$);
#972=IFCSHAPEREPRESENTATION(#16,'Body','Curve2D',(#919));
#973=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#971));
#974=IFCGEOGRAPHICELEMENTTYPE('1t393Epk10ahdDnhnFR8sr',$,'Tree Medium (5m)',$,$,$,(#979,#984),$,$,.NOTDEFINED.);
#975=IFCCARTESIANPOINT((0.,0.,0.));
#976=IFCDIRECTION((1.,0.,0.));
#977=IFCDIRECTION((0.,0.,1.));
#978=IFCAXIS2PLACEMENT3D(#975,#977,#976);
#979=IFCREPRESENTATIONMAP(#978,#973);
#980=IFCCARTESIANPOINT((0.,0.,0.));
#981=IFCDIRECTION((1.,0.,0.));
#982=IFCDIRECTION((0.,0.,1.));
#983=IFCAXIS2PLACEMENT3D(#980,#982,#981);
#984=IFCREPRESENTATIONMAP(#983,#972);
ENDSEC;
END-ISO-10303-21;
+2 -2
View File
@@ -80,8 +80,8 @@ class IfcStore:
if IfcStore.path:
try:
IfcStore.load_file(IfcStore.path)
except:
pass
except Exception as e:
print(f"Failed to load file {IfcStore.path}. Error details: {e}")
return IfcStore.file
@staticmethod
@@ -49,7 +49,17 @@ classes = (
operator.SwitchRepresentation,
operator.UpdateParametricRepresentation,
operator.UpdateRepresentation,
operator.RemoveRepresentationItem,
operator.EnableEditingRepresentationItemStyle,
operator.EditRepresentationItemStyle,
operator.DisableEditingRepresentationItemStyle,
operator.UnassignRepresentationItemStyle,
operator.EnableEditingRepresentationItemShapeAspect,
operator.EditRepresentationItemShapeAspect,
operator.DisableEditingRepresentationItemShapeAspect,
operator.RemoveRepresentationItemFromShapeAspect,
prop.RepresentationItem,
prop.ShapeAspect,
prop.BIMObjectGeometryProperties,
prop.BIMGeometryProperties,
ui.BIM_PT_placement,
@@ -93,7 +103,9 @@ def register():
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new("bim.override_object_duplicate_move_linked_macro", "D", "PRESS", alt=True)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new("bim.object_duplicate_move_linked_aggregate_macro", "D", "PRESS", ctrl=True, shift=True)
kmi = km.keymap_items.new(
"bim.object_duplicate_move_linked_aggregate_macro", "D", "PRESS", ctrl=True, shift=True
)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new("bim.override_paste_buffer", "V", "PRESS", ctrl=True)
addon_keymaps.append((km, kmi))
@@ -38,6 +38,7 @@ class RepresentationsData:
def load(cls):
cls.data = {"representations": cls.representations()}
cls.data["contexts"] = cls.contexts()
cls.data["shape_aspects"] = cls.shape_aspects()
cls.is_loaded = True
@classmethod
@@ -92,6 +93,24 @@ class RepresentationsData:
)
return results
@classmethod
def shape_aspects(cls):
obj = bpy.context.active_object
element = tool.Ifc.get_entity(obj)
active_representation_id = obj.data.BIMMeshProperties.ifc_definition_id
base_representation = tool.Ifc.get().by_id(active_representation_id)
# shape aspects matching context of the active representation
matching_shape_aspects = []
for shape_aspect in tool.Geometry.get_shape_aspects(element):
matching_representation = tool.Geometry.get_shape_aspect_representation(shape_aspect, base_representation)
if matching_representation:
matching_shape_aspects.append(shape_aspect)
# blender enum items
new_shape_aspect = [("NEW", "Create A New Shape Aspect", "")]
return new_shape_aspect + [(str(s.id()), s.Name or "Unnamed", "") for s in matching_shape_aspects]
class RepresentationItemsData:
data = {}
@@ -767,11 +767,13 @@ class OverrideDuplicateMove(bpy.types.Operator):
element = tool.Ifc.get_entity(obj)
if element:
if element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
self.report({'INFO'}, "Did not duplicate. Duplicate drawings through the Drawings and Documents UI.")
self.report(
{"INFO"}, "Did not duplicate. Duplicate drawings through the Drawings and Documents UI."
)
obj.select_set(False)
continue # For now, don't copy drawings until we stabilise a bit more. It's tricky.
elif element.is_a("IfcProject"):
self.report({'INFO'}, "Did not duplicate. IFC can only have one project.")
self.report({"INFO"}, "Did not duplicate. IFC can only have one project.")
obj.select_set(False)
continue # Only one IfcProject is allowed.
@@ -1590,6 +1592,11 @@ class EnableEditingRepresentationItems(bpy.types.Operator, Operator):
new.surface_style = style.Name or "Unnamed"
elif inverse.is_a("IfcPresentationLayerAssignment"):
new.layer = inverse.Name or "Unnamed"
elif inverse.is_a("IfcShapeRepresentation"):
if inverse.OfShapeAspect:
shape_aspect = inverse.OfShapeAspect[0]
new.shape_aspect = shape_aspect.Name
new.shape_aspect_id = shape_aspect.id()
class DisableEditingRepresentationItems(bpy.types.Operator, Operator):
@@ -1600,3 +1607,195 @@ class DisableEditingRepresentationItems(bpy.types.Operator, Operator):
def _execute(self, context):
obj = context.active_object
obj.BIMGeometryProperties.is_editing = False
class RemoveRepresentationItem(bpy.types.Operator, Operator):
bl_idname = "bim.remove_representation_item"
bl_label = "Remove Representation Item"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
if context.active_object is None or len(context.active_object.BIMGeometryProperties.items) <= 1:
cls.poll_message_set(
"Active object need to have more than 1 representation items to keep representation valid"
)
return False
return True
def _execute(self, context):
obj = context.active_object
props = obj.BIMGeometryProperties
ifc_file = tool.Ifc.get()
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = ifc_file.by_id(representation_item_id)
tool.Geometry.remove_representation_item(representation_item)
tool.Geometry.reload_representation(obj)
# reload style ui
bpy.ops.bim.disable_editing_representation_items()
bpy.ops.bim.enable_editing_representation_items()
class EnableEditingRepresentationItemStyle(bpy.types.Operator, Operator):
bl_idname = "bim.enable_editing_representation_item_style"
bl_label = "Enable Editing Representation Item Style"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.active_object.BIMGeometryProperties
props.is_editing_item_style = True
ifc_file = tool.Ifc.get()
# set dropdown to currently active style
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = ifc_file.by_id(representation_item_id)
style = tool.Style.get_representation_item_style(representation_item)
if style:
props.representation_item_style = str(style.id())
class EditRepresentationItemStyle(bpy.types.Operator, Operator):
bl_idname = "bim.edit_representation_item_style"
bl_label = "Edit Representation Item Style"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
obj = context.active_object
props = obj.BIMGeometryProperties
props.is_editing_item_style = False
ifc_file = tool.Ifc.get()
surface_style = ifc_file.by_id(int(props.representation_item_style))
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = ifc_file.by_id(representation_item_id)
tool.Style.assign_style_to_representation_item(representation_item, surface_style)
tool.Geometry.reload_representation(obj)
# reload style ui
bpy.ops.bim.disable_editing_representation_items()
bpy.ops.bim.enable_editing_representation_items()
class DisableEditingRepresentationItemStyle(bpy.types.Operator, Operator):
bl_idname = "bim.disable_editing_representation_item_style"
bl_label = "Disable Editing Representation Item Style"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.active_object.BIMGeometryProperties
props.is_editing_item_style = False
class UnassignRepresentationItemStyle(bpy.types.Operator, Operator):
bl_idname = "bim.unassign_representation_item_style"
bl_label = "Unassign Representation Item Style"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
obj = context.active_object
props = obj.BIMGeometryProperties
props.is_editing_item_style = False
# get active representation item
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = tool.Ifc.get_entity_by_id(representation_item_id)
if not representation_item:
self.report({"ERROR"}, f"Couldn't find representation item by id {representation_item_id}.")
return {"CANCELLED"}
tool.Style.assign_style_to_representation_item(representation_item, None)
tool.Geometry.reload_representation(obj)
# reload style ui
bpy.ops.bim.disable_editing_representation_items()
bpy.ops.bim.enable_editing_representation_items()
class EnableEditingRepresentationItemShapeAspect(bpy.types.Operator, Operator):
bl_idname = "bim.enable_editing_representation_item_shape_aspect"
bl_label = "Enable Editing Representation Item Shape Aspect"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.active_object.BIMGeometryProperties
props.is_editing_item_shape_aspect = True
# set dropdown to currently active shape aspect
shape_aspect_id = props.items[props.active_item_index].shape_aspect_id
if shape_aspect_id != 0:
props.representation_item_shape_aspect = str(shape_aspect_id)
class EditRepresentationItemShapeAspect(bpy.types.Operator, Operator):
bl_idname = "bim.edit_representation_item_shape_aspect"
bl_label = "Edit Representation Item Shape Aspect"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
obj = context.active_object
element = tool.Ifc.get_entity(obj)
props = obj.BIMGeometryProperties
props.is_editing_item_shape_aspect = False
ifc_file = tool.Ifc.get()
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = ifc_file.by_id(representation_item_id)
if props.representation_item_shape_aspect == "NEW":
active_representation = tool.Geometry.get_active_representation(obj)
# find IfcProductRepresentationSelect based on current representation
if hasattr(element, "Representation"): # IfcProduct
product_shape = element.Representation
else: # IfcTypeProduct
for representation_map in element.RepresentationMaps:
if representation_map.MappedRepresentation == active_representation:
product_shape = representation_map
previous_shape_aspect_id = props.items[props.active_item_index].shape_aspect_id
# will be None if item didn't had a shape aspect
previous_shape_aspect = tool.Ifc.get_entity_by_id(previous_shape_aspect_id)
shape_aspect = tool.Geometry.create_shape_aspect(
product_shape, active_representation, [representation_item], previous_shape_aspect
)
else:
shape_aspect = ifc_file.by_id(int(props.representation_item_shape_aspect))
tool.Geometry.add_representation_item_to_shape_aspect([representation_item], shape_aspect)
# set attributes from UI
shape_aspect_attrs = props.shape_aspect_attrs
shape_aspect.Name = shape_aspect_attrs.name
shape_aspect.Description = shape_aspect_attrs.description
# reload style ui
bpy.ops.bim.disable_editing_representation_items()
bpy.ops.bim.enable_editing_representation_items()
class DisableEditingRepresentationItemShapeAspect(bpy.types.Operator, Operator):
bl_idname = "bim.disable_editing_representation_item_shape_aspect"
bl_label = "Disable Editing Representation Item Shape Aspect"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.active_object.BIMGeometryProperties
props.is_editing_item_shape_aspect = False
class RemoveRepresentationItemFromShapeAspect(bpy.types.Operator, Operator):
bl_idname = "bim.remove_representation_item_from_shape_aspect"
bl_label = "Remove Representation Item From Shape Aspect"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
obj = context.active_object
props = obj.BIMGeometryProperties
ifc_file = tool.Ifc.get()
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = ifc_file.by_id(representation_item_id)
shape_aspect = ifc_file.by_id(props.items[props.active_item_index].shape_aspect_id)
tool.Geometry.remove_representation_items_from_shape_aspect([representation_item], shape_aspect)
# reload style ui
bpy.ops.bim.disable_editing_representation_items()
bpy.ops.bim.enable_editing_representation_items()
@@ -17,6 +17,7 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy
import blenderbim.tool as tool
from blenderbim.bim.prop import StrProperty, Attribute
from blenderbim.bim.module.geometry.data import RepresentationsData
from bpy.types import PropertyGroup
@@ -47,11 +48,60 @@ def update_mode(self, context):
bpy.ops.bim.override_mode_set_edit("INVOKE_DEFAULT")
def get_styles(self, context):
# postponed import to avoid circular import
from blenderbim.bim.module.material.data import MaterialsData
if not MaterialsData.is_loaded:
MaterialsData.load()
return MaterialsData.data["styles"]
def get_shape_aspects(self, context):
if not RepresentationsData.is_loaded:
RepresentationsData.load()
return RepresentationsData.data["shape_aspects"]
def get_material_constituents(self, context, edit_text):
# TODO: cache in data.py
return [m.Name for m in tool.Ifc.get().by_type("IfcMaterialConstituent") if m.Name]
def update_shape_aspect(self, context):
shape_aspect_id = self.representation_item_shape_aspect
attrs = self.shape_aspect_attrs
if shape_aspect_id == "NEW": # new shape aspect
attrs.name = tool.Blender.get_blender_prop_default_value(attrs, "name")
attrs.description = tool.Blender.get_blender_prop_default_value(attrs, "description")
else:
shape_aspect = tool.Ifc.get().by_id(int(shape_aspect_id))
attrs.name = shape_aspect.Name or ""
attrs.description = shape_aspect.Description or ""
class RepresentationItem(PropertyGroup):
name: StringProperty(name="Name")
surface_style: StringProperty(name="Surface Style")
layer: StringProperty(name="Layer")
ifc_definition_id: IntProperty(name="IFC Definition ID")
shape_aspect: StringProperty(name="Shape Aspect")
shape_aspect_id: IntProperty(name="Shape Aspect IFC ID")
class ShapeAspect(PropertyGroup):
name: StringProperty(
name="Name",
description=(
"Note that IfcMaterialConstituent is applied based on shape aspects using the same name as material constituent.\n"
"In dropdown suggestions you can see names of existing material constituents."
),
search=get_material_constituents,
)
description: StringProperty(
name="Description",
)
class BIMObjectGeometryProperties(PropertyGroup):
@@ -59,6 +109,13 @@ class BIMObjectGeometryProperties(PropertyGroup):
is_editing: BoolProperty(name="Is Editing", default=False)
items: CollectionProperty(name="Representation Items", type=RepresentationItem)
active_item_index: IntProperty(name="Active Representation Item Index")
is_editing_item_style: BoolProperty(name="Is Editing Item's Style", default=False)
representation_item_style: EnumProperty(items=get_styles, name="Representation Item Style")
is_editing_item_shape_aspect: BoolProperty(name="Is Editing Item's Shape Aspect", default=False)
representation_item_shape_aspect: EnumProperty(
items=get_shape_aspects, name="Representation Item Shape Aspect", update=update_shape_aspect
)
shape_aspect_attrs: PointerProperty(type=ShapeAspect)
class BIMGeometryProperties(PropertyGroup):
@@ -29,6 +29,7 @@ from blenderbim.bim.module.geometry.data import (
PlacementData,
DerivedCoordinatesData,
)
from blenderbim.bim.module.layer.data import LayersData
def mode_menu(self, context):
@@ -133,6 +134,7 @@ class BIM_PT_representations(Panel):
if not RepresentationsData.data["representations"]:
layout.label(text="No Representations Found")
return
for representation in RepresentationsData.data["representations"]:
row = self.layout.row(align=True)
@@ -150,6 +152,18 @@ class BIM_PT_representations(Panel):
op.ifc_definition_id = representation["id"]
op.disable_opening_subtractions = False
row.operator("bim.remove_representation", icon="X", text="").representation_id = representation["id"]
if representation["is_active"]:
active_representation = representation
layout.separator()
if not LayersData.is_loaded:
LayersData.load()
if LayersData.data["active_layers"]:
layout.label(text="Representation Presentation Layers:")
for layer_name in LayersData.data["active_layers"].values():
layout.label(text=layer_name, icon="STICKY_UVS_LOC")
else:
layout.label(text="Representation Has No Presentation Layers", icon="STICKY_UVS_LOC")
class BIM_PT_representation_items(Panel):
@@ -187,20 +201,47 @@ class BIM_PT_representation_items(Panel):
self.layout.template_list("BIM_UL_representation_items", "", props, "items", props, "active_item_index")
item_is_active = props.active_item_index < len(props.items)
if item_is_active:
surface_style = props.items[props.active_item_index].surface_style
presentation_layer = props.items[props.active_item_index].layer
if not item_is_active:
return
active_item = props.items[props.active_item_index]
surface_style = active_item.surface_style
shape_aspect = active_item.shape_aspect
row = self.layout.row(align=True)
if props.is_editing_item_style:
# NOTE: we currently support 1 item having just 1 style
# when IfcStyledItem can actually have multiple styles
row.prop(props, "representation_item_style", icon="SHADING_RENDERED", text="")
row.operator("bim.edit_representation_item_style", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_representation_item_style", icon="CANCEL", text="")
else:
surface_style, presentation_layer = None, None
if surface_style:
row.label(text=surface_style, icon="SHADING_RENDERED")
else:
row.label(text="No Surface Style", icon="MESH_UVSPHERE")
row.operator("bim.enable_editing_representation_item_style", icon="GREASEPENCIL", text="")
if surface_style:
row.operator("bim.unassign_representation_item_style", icon="X", text="")
row = self.layout.row()
if surface_style:
row.label(text=surface_style, icon="SHADING_RENDERED")
else:
row.label(text="No Surface Style", icon="MESH_UVSPHERE")
row.label(text=active_item.layer or "No Presentation Layer", icon="STICKY_UVS_LOC")
row = self.layout.row()
row.label(text=presentation_layer or "No Presentation Layer", icon="STICKY_UVS_LOC")
row = self.layout.row(align=True)
if props.is_editing_item_shape_aspect:
row.prop(props, "representation_item_shape_aspect", icon="SHAPEKEY_DATA", text="")
row.operator("bim.edit_representation_item_shape_aspect", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_representation_item_shape_aspect", icon="CANCEL", text="")
shape_aspect_attrs = props.shape_aspect_attrs
self.layout.label(text="Shape Aspect Attributes:")
self.layout.prop(shape_aspect_attrs, "name")
self.layout.prop(shape_aspect_attrs, "description")
else:
row.label(text=shape_aspect or "No Shape Aspect", icon="SHAPEKEY_DATA")
row.operator("bim.enable_editing_representation_item_shape_aspect", icon="GREASEPENCIL", text="")
if shape_aspect:
row.operator("bim.remove_representation_item_from_shape_aspect", icon="X", text="")
class BIM_PT_connections(Panel):
@@ -469,3 +510,4 @@ class BIM_UL_representation_items(UIList):
row.label(text=item.name, icon=icon)
if item.layer:
row.label(text="", icon="STICKY_UVS_LOC")
row.operator("bim.remove_representation_item", icon="X", text="")
@@ -40,14 +40,15 @@ class LayersData:
@classmethod
def active_layers(cls):
if not bpy.context.active_object:
return []
data = bpy.context.active_object.data
if not data:
return []
if not isinstance(data, bpy.types.Mesh) or not data.BIMMeshProperties.ifc_definition_id:
return []
results = []
results = dict()
shape = tool.Ifc.get().by_id(data.BIMMeshProperties.ifc_definition_id)
for inverse in tool.Ifc.get().get_inverse(shape):
if inverse.is_a("IfcPresentationLayerAssignment"):
results.append(inverse.id())
for inverse in shape.LayerAssignments:
results[inverse.id()] = inverse.Name or "Unnamed"
return results
@@ -137,6 +137,7 @@ class RemovePresentationLayer(bpy.types.Operator):
class AssignPresentationLayer(bpy.types.Operator):
bl_idname = "bim.assign_presentation_layer"
bl_label = "Assign Presentation Layer"
bl_description = "Assign presentation layer to the active representation of the active object"
bl_options = {"REGISTER", "UNDO"}
item: bpy.props.StringProperty()
layer: bpy.props.IntProperty()
@@ -158,6 +159,7 @@ class AssignPresentationLayer(bpy.types.Operator):
class UnassignPresentationLayer(bpy.types.Operator):
bl_idname = "bim.unassign_presentation_layer"
bl_label = "Unassign Presentation Layer"
bl_description = "Unassign presentation layer from the active representation of the active object"
bl_options = {"REGISTER", "UNDO"}
item: bpy.props.StringProperty()
layer: bpy.props.IntProperty()
@@ -84,6 +84,7 @@ class BIM_UL_layers(UIList):
op = row.operator("bim.assign_presentation_layer", text="", icon="KEYFRAME", emboss=False)
op.layer = item.ifc_definition_id
# TODO: replace placeholder UI for hiding presentation layers
row.operator("bim.disable_editing_layer", text="", icon="HIDE_OFF", emboss=False)
row.operator("bim.disable_editing_layer", text="", icon="FREEZE", emboss=False)
@@ -521,6 +521,7 @@ class AddBoolean(Operator, tool.Ifc.Operator):
return {"FINISHED"}
if element2 and not element1:
obj1, obj2 = obj2, obj1
element1, element2 = element2, element1
if not obj1.data or not hasattr(obj1.data, "BIMMeshProperties"):
return {"FINISHED"}
representation = tool.Ifc.get().by_id(obj1.data.BIMMeshProperties.ifc_definition_id)
@@ -668,17 +669,17 @@ class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
except:
continue
boolean = None
boolean_id = None
for inverse in tool.Ifc.get().get_inverse(item):
if inverse.is_a("IfcBooleanResult"):
boolean = inverse
boolean_id = inverse.id()
break
ifcopenshell.api.run("geometry.remove_boolean", tool.Ifc.get(), item=item)
if obj.data.BIMMeshProperties.obj:
upstream_obj = obj.data.BIMMeshProperties.obj
element = tool.Ifc.get_entity(upstream_obj)
bbim_boolean_updates.setdefault(element, []).append(boolean)
bbim_boolean_updates.setdefault(element, []).append(boolean_id)
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if body:
blenderbim.core.geometry.switch_representation(
@@ -692,8 +693,8 @@ class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
)
bpy.data.objects.remove(obj)
for element, booleans in bbim_boolean_updates.items():
tool.Model.unmark_manual_booleans(element, booleans)
for element, boolean_ids in bbim_boolean_updates.items():
tool.Model.unmark_manual_booleans(element, boolean_ids)
tool.Blender.set_active_object(upstream_obj)
return {"FINISHED"}
@@ -29,8 +29,9 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_opening"
bl_label = "Add Opening"
bl_options = {"REGISTER", "UNDO"}
bl_description = "Adds an opening to an element.\n" \
"Need to select two elements, order of selection is not important"
bl_description = (
"Adds an opening to an element.\n" "Need to select two elements, order of selection is not important"
)
@classmethod
def poll(cls, context):
@@ -41,12 +42,10 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context):
props = context.scene.BIMModelProperties
selected_objects = context.selected_objects
target_object = selected_objects[0]
target_object = selected_objects[0]
opening_objects = [obj for obj in selected_objects if obj != target_object]
for opening_obj in opening_objects:
element1 = tool.Ifc.get_entity(target_object)
obj1 = target_object
@@ -58,7 +57,7 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator):
if element1 and element2:
if element1.is_a("IfcOpeningElement") and element2.is_a("IfcOpeningElement"):
self.report({'INFO'}, "You can't add an opening to another opening.")
self.report({"INFO"}, "You can't add an opening to another opening.")
continue
elif not element1.is_a("IfcOpeningElement") and not element2.is_a("IfcOpeningElement"):
if element1.is_a("IfcWindow") or element1.is_a("IfcDoor"): # Add a fill to an element.
@@ -75,7 +74,7 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator):
element1, element2 = element2, element1
if element1.is_a("IfcOpeningElement"):
self.report({'INFO'}, "You can't add an opening to another opening.")
self.report({"INFO"}, "You can't add an opening to another opening.")
continue
if tool.Ifc.is_moved(obj1):
@@ -259,8 +258,10 @@ class BooleansMarkAsManual(bpy.types.Operator):
if self.mark_as_manual:
tool.Model.mark_manual_booleans(element, booleans)
else:
tool.Model.unmark_manual_booleans(element, booleans)
tool.Model.unmark_manual_booleans(element, [b.id() for b in booleans])
self.report({"INFO"}, f"{len(booleans)} were marked as {'manual' if self.mark_as_manual else 'automatic'}")
self.report(
{"INFO"}, f"{len(booleans)} booleans were marked as {'manual' if self.mark_as_manual else 'automatic'}"
)
blenderbim.bim.handler.refresh_ui_data()
return {"FINISHED"}
+160 -1
View File
@@ -299,6 +299,7 @@ class Geometry(blenderbim.core.tool.Geometry):
@classmethod
def get_active_representation(cls, obj):
"""< IfcShapeRepresentation or None"""
if obj.data and hasattr(obj.data, "BIMMeshProperties") and obj.data.BIMMeshProperties.ifc_definition_id:
return tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
@@ -441,7 +442,7 @@ class Geometry(blenderbim.core.tool.Geometry):
return styles
usage_count = [0] * len(obj.material_slots)
if not usage_count: # if there are no materials, polygons will still use index 0
if not usage_count: # if there are no materials, polygons will still use index 0
return []
for poly in obj.data.polygons:
usage_count[poly.material_index] += 1
@@ -716,3 +717,161 @@ class Geometry(blenderbim.core.tool.Geometry):
obj.matrix_world.translation += original_min_point - new_max_point
bpy.context.view_layer.update()
@classmethod
def reload_representation(cls, obj):
representation = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
blenderbim.core.geometry.switch_representation(
tool.Ifc,
tool.Geometry,
obj=obj,
representation=representation,
should_reload=True,
is_global=True,
should_sync_changes_first=False,
apply_openings=True,
)
@classmethod
def remove_representation_item(cls, representation_item):
# NOTE: we assume it's not the last representation item
# otherwise we probably would need to remove representation too
# NOTE: a lot of shared code with `geometry.remove_representation`
ifc_file = tool.Ifc.get()
shape_aspects = []
consider_inverses = []
styled_item, colour, texture, layer = None, None, None, None
[consider_inverses.append(styled_item := t) for t in representation_item.StyledByItem]
[consider_inverses.append(layer := t) for t in representation_item.LayerAssignment]
# IfcTessellatedFaceSet
[consider_inverses.append(colour := t) for t in getattr(representation_item, "HasColours", [])]
[consider_inverses.append(texture := t) for t in getattr(representation_item, "HasTextures", [])]
for inverse in ifc_file.get_inverse(representation_item):
if inverse.is_a("IfcShapeRepresentation"):
if inverse.OfShapeAspect:
shape_aspects.append(inverse.OfShapeAspect[0])
else:
representation = inverse
if styled_item:
ifc_file.remove(styled_item)
if layer and len(layer.Items) == 1:
ifc_file.remove(styled_item)
if colour:
ifcopenshell.util.element.remove_deep2(ifc_file, colour)
if texture:
ifcopenshell.util.element.remove_deep2(ifc_file, texture)
for shape_aspect in shape_aspects:
cls.remove_representation_items_from_shape_aspect([representation_item], shape_aspect)
representation.Items = tuple(set(representation.Items) - {representation_item})
also_consider = list(consider_inverses)
ifcopenshell.util.element.remove_deep2(ifc_file, representation_item, also_consider=also_consider)
@classmethod
def get_shape_aspects(cls, element):
# IfcProduct
if hasattr(element, "Representation"):
return element.Representation.HasShapeAspects
# IfcTypeProduct
shape_aspects = []
for repersentation_map in element.RepresentationMaps:
shape_aspects += repersentation_map.HasShapeAspects
return shape_aspects
@classmethod
def create_shape_aspect(cls, product_shape, base_representation, items, previous_shape_aspect=None):
"""
> `product_shape` - IfcProductDefinitionShape or IfcRepresentationMap\n
> `base_representation` - base representation to get context attributes from\n
> `items` - representation items\n
> `previous_shape_aspect` - (optional) previous shape aspect, if provided\n
items will be removed the previous shape aspect first\n
< IfcShapeAspect
"""
if previous_shape_aspect is not None:
cls.remove_representation_items_from_shape_aspect(items, previous_shape_aspect)
shape_aspect = tool.Ifc.get().createIfcShapeAspect(
PartOfProductDefinitionShape=product_shape, ShapeRepresentations=()
)
# keep IfcShapeAspect and IfcShapeRepresentation valid
rep = tool.Geometry.add_shape_aspect_representation(shape_aspect, base_representation)
rep.Items = items
return shape_aspect
@classmethod
def remove_representation_items_from_shape_aspect(cls, representation_items, shape_aspect):
ifc_file = tool.Ifc.get()
# as shape aspect might have multiple representations
# it's easier to find it from the item
for inverse in ifc_file.get_inverse(representation_items[0]):
if inverse.is_a("IfcShapeRepresentation") and shape_aspect in inverse.OfShapeAspect:
representation = inverse
break
# removing last item would make representation invalid
if len(representation.Items) == len(representation_items):
# removing last representation would make shape aspect invalid.
# remove shape aspect first otherwise remove_representation won't remove it because of the inverse
if len(shape_aspect.ShapeRepresentations) == 1:
ifc_file.remove(shape_aspect)
tool.Ifc.run("geometry.remove_representation", representation=representation)
else:
items = set(representation.Items) - set(representation_items)
representation.Items = tuple(items)
@classmethod
def add_representation_item_to_shape_aspect(cls, representation_items, shape_aspect):
"""NOTE: we assume that all items belonged to the same representation and to the same shape aspect"""
ifc_file = tool.Ifc.get()
previous_shape_aspect = None
for inverse in ifc_file.get_inverse(representation_items[0]):
if inverse.is_a("IfcShapeRepresentation"):
if inverse.OfShapeAspect:
# item is already added to the shape aspect
if inverse.OfShapeAspect[0] == shape_aspect:
return
previous_shape_aspect = inverse.OfShapeAspect[0]
else:
base_representation = inverse
# remove item from previous shape aspect
if previous_shape_aspect:
cls.remove_representation_items_from_shape_aspect(representation_items, previous_shape_aspect)
shape_aspect_representation = cls.get_shape_aspect_representation(
shape_aspect, base_representation, create_new=True
)
shape_aspect_representation.Items = shape_aspect_representation.Items + tuple(representation_items)
@classmethod
def get_shape_aspect_representation(cls, shape_aspect, base_representation, create_new=False):
for representation in shape_aspect.ShapeRepresentations:
if (
representation.ContextOfItems == base_representation.ContextOfItems
and representation.RepresentationIdentifier == base_representation.RepresentationIdentifier
and representation.RepresentationType == base_representation.RepresentationType
):
return representation
if not create_new:
return None
return cls.add_shape_aspect_representation(shape_aspect, base_representation)
@classmethod
def add_shape_aspect_representation(cls, shape_aspect, base_representation):
shape_aspect_representation = tool.Ifc.get().createIfcShapeRepresentation(
ContextOfItems=base_representation.ContextOfItems,
RepresentationIdentifier=base_representation.RepresentationIdentifier,
RepresentationType=base_representation.RepresentationType,
)
shape_aspect.ShapeRepresentations = shape_aspect.ShapeRepresentations + (shape_aspect_representation,)
return shape_aspect_representation
+9 -8
View File
@@ -415,24 +415,25 @@ class IfcGit:
@classmethod
def config_ifcmerge(cls):
config_reader = IfcGitRepo.repo.config_reader()
config_writer = IfcGitRepo.repo.config_writer()
section = 'mergetool "ifcmerge"'
if not config_reader.has_section(section):
config_writer.set_value(section, "cmd", "ifcmerge $BASE $LOCAL $REMOTE $MERGED")
config_writer.set_value(section, "trustExitCode", True)
with IfcGitRepo.repo.config_writer() as config_writer:
config_writer.set_value(section, "cmd", "ifcmerge $BASE $LOCAL $REMOTE $MERGED")
config_writer.set_value(section, "trustExitCode", True)
section = 'mergetool "ifcmerge-forward"'
if not config_reader.has_section(section):
config_writer.set_value(section, "cmd", "ifcmerge $BASE $REMOTE $LOCAL $MERGED")
config_writer.set_value(section, "trustExitCode", True)
with IfcGitRepo.repo.config_writer() as config_writer:
config_writer.set_value(section, "cmd", "ifcmerge $BASE $REMOTE $LOCAL $MERGED")
config_writer.set_value(section, "trustExitCode", True)
@classmethod
def config_push(cls, repo):
"""Set push.autoSetupRemote"""
config_reader = repo.config_reader()
config_writer = repo.config_writer()
if not config_reader.has_section("push"):
config_writer.set_value("push", "default", "current")
config_writer.set_value("push", "autoSetupRemote", True)
with repo.config_writer() as config_writer:
config_writer.set_value("push", "default", "current")
config_writer.set_value("push", "autoSetupRemote", True)
@classmethod
def config_info_attributes(cls, repo):
+8 -7
View File
@@ -478,7 +478,7 @@ class Model(blenderbim.core.tool.Model):
return {"thickness": thickness, "offset": offset, "direction_sense": direction_sense}
@classmethod
def get_booleans(cls, element=None, representation=None):
def get_booleans(cls, element=None, representation=None) -> list[ifcopenshell.entity_instance]:
if representation is None:
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if not representation:
@@ -493,7 +493,7 @@ class Model(blenderbim.core.tool.Model):
return booleans
@classmethod
def get_manual_booleans(cls, element, representation=None):
def get_manual_booleans(cls, element, representation=None) -> list[ifcopenshell.entity_instance]:
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
if not pset:
return []
@@ -502,7 +502,7 @@ class Model(blenderbim.core.tool.Model):
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if not representation:
return []
booleans = [b for b in cls.get_booleans(element) if b.id() in boolean_ids]
booleans = [b for b in cls.get_booleans(element, representation) if b.id() in boolean_ids]
return booleans
@classmethod
@@ -521,11 +521,12 @@ class Model(blenderbim.core.tool.Model):
ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": data})
@classmethod
def unmark_manual_booleans(cls, element, booleans):
def unmark_manual_booleans(cls, element, boolean_ids):
# NOTE: we use use boolean_ids instead of boolean entities
# so it will be possible to unmark manual booleans after they already was deleted
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
if not pset:
return
boolean_ids = [b.id() for b in booleans]
data = set(json.loads(pset["Data"]))
data -= set(boolean_ids)
data = list(data)
@@ -978,8 +979,8 @@ class Model(blenderbim.core.tool.Model):
if nosing_length < 0: # tread gaps
length += abs(nosing_length) * number_of_treads
calculated_params["Length"] = round(length, 5)
pitch = height/length
pitch_formatted = str(round(pitch*100, 1)) + ' % / ' + str(round(degrees(atan(pitch)), 1)) + ' deg'
pitch = height / length
pitch_formatted = str(round(pitch * 100, 1)) + " % / " + str(round(degrees(atan(pitch)), 1)) + " deg"
calculated_params["Pitch"] = str(pitch_formatted)
return calculated_params
+1 -1
View File
@@ -181,7 +181,7 @@ class Qto(blenderbim.core.tool.Qto):
"quantity_value" : XX,
"quantity_type" : XX
}]
:rtype list
:rtype: list
Example:
+21
View File
@@ -549,6 +549,27 @@ class Style(blenderbim.core.tool.Style):
representation = tool.Geometry.get_active_representation(obj)
tool.Ifc.run("style.assign_representation_styles", shape_representation=representation, styles=[style])
@classmethod
def assign_style_to_representation_item(cls, representation_item, style=None):
ifc_file = tool.Ifc.get()
if not representation_item.StyledByItem:
if style is None:
return
ifc_file.createIfcStyledItem(representation_item, (style,))
styled_item = representation_item.StyledByItem[0]
if style is None:
ifc_file.remove(styled_item)
return
styled_item.Styles = (style,)
@classmethod
def get_representation_item_style(cls, representation_item):
for inverse in tool.Ifc.get().get_inverse(representation_item):
if inverse.is_a("IfcStyledItem"):
for style in inverse.Styles:
return style
@classmethod
def reload_material_from_ifc(cls, blender_material):
blender_material.BIMStyleProperties.active_style_type = blender_material.BIMStyleProperties.active_style_type
@@ -25,18 +25,16 @@ from ifcopenshell.util.shape_builder import ShapeBuilder, V
class LibraryGenerator:
def generate(self, output_filename="IFC4 EU Steel.ifc"):
def generate(self, library_name, output_filename="IFC4 EU Steel.ifc"):
ifcopenshell.api.pre_listeners = {}
ifcopenshell.api.post_listeners = {}
self.materials = {}
self.file = ifcopenshell.api.run("project.create_file")
self.project = ifcopenshell.api.run(
"root.create_entity", self.file, ifc_class="IfcProject", name=f"Non-structural assets library"
)
self.project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject", name=library_name)
self.library = ifcopenshell.api.run(
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=f"Non-structural assets library"
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=library_name
)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definition=self.library, relating_context=self.project
@@ -1876,4 +1874,6 @@ class LibraryGenerator:
if __name__ == "__main__":
path = Path(__file__).parents[1] / "blenderbim/bim/data/libraries"
LibraryGenerator().generate(output_filename=str(path / "IFC4 Furniture Library.ifc"))
LibraryGenerator().generate(
"Non-structural assets library", output_filename=str(path / "IFC4 Furniture Library.ifc")
)
@@ -0,0 +1,403 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2024 @Andrej730
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api
import random
from math import cos, sin, tan, pi
from pathlib import Path
from itertools import chain
from ifcopenshell.util.shape_builder import ShapeBuilder, V
from collections import namedtuple
from mathutils import Vector, Matrix
from random import uniform
SimpleTreeParams = namedtuple("SimpleTreeParams", "plant_height crown_diameter trunk_diameter")
LowPolyTreeParams = namedtuple(
"LowPolyTreeParams", "plant_height crown_diameter crown_max_loc crown_taper trunk_height trunk_diameter random_seed"
)
PalmTreeParams = namedtuple("PalmTreeParams", "plant_height crown_diameter trunk_diameter")
TreePresetData = namedtuple("TreePresetData", "preset_class generator")
GeneratedGeometry = namedtuple("GeneratedGeometry", "items_2d items_3d")
def generate_low_poly_tree(
builder: ShapeBuilder,
crown_taper=0.5,
crown_max_loc=0.3,
plant_height=12.0,
trunk_height=2.0,
crown_diameter=4,
trunk_diameter=0.3,
random_seed=10,
) -> GeneratedGeometry:
unit_conversion = 1 / ifcopenshell.util.unit.calculate_unit_scale(builder.file)
random.seed(random_seed)
res = 6
plant_height *= unit_conversion
trunk_height *= unit_conversion
crown_diameter *= unit_conversion
trunk_diameter *= unit_conversion
crown_height = plant_height - trunk_height
def circle(center, r, res):
points = []
for i in range(res):
# fmt: off
vert = (
cos(i * 2 * pi / res) * r + center[0],
sin(i * 2 * pi / res) * r + center[1],
0.0 + center[2]
)
# fmt: on
points.append(vert)
return points
def merge_lists(lists):
merged_list = []
for i in range(len(lists)):
merged_list = merged_list + lists[i]
return merged_list
def XY_scale(vert, scale):
vert_scaled = (vert[0] * scale, vert[1] * scale, vert[2])
return vert_scaled
def rand_add(vert, amp):
# fmt: off
vert_new = (
vert[0] + uniform(-amp, amp),
vert[1] + uniform(-amp, amp),
vert[2] + uniform(-amp, amp)
)
# fmt: on
return vert_new
height_segments_trunk = 2
height_segments_crown = 7
height_segments_total = height_segments_trunk + height_segments_crown
verts = []
# Trunk
for i in range(height_segments_trunk):
points = circle((0.0, 0.0, i * trunk_height), trunk_diameter / 2, res)
verts.append(points)
# Crown
h_crown_max_loc = int((height_segments_crown - 1) * crown_max_loc)
crown_indices = []
for i in range(0, h_crown_max_loc):
crown_indices.append(i)
for i in range(0, height_segments_crown - h_crown_max_loc):
crown_indices.append(h_crown_max_loc - i)
my_min_val = min(crown_indices)
my_max_val = max(crown_indices)
n_crown_taper = crown_taper * 0.8
crown_diameters = []
for x in crown_indices:
crown_diameters.append(((x - my_min_val) / (my_max_val - my_min_val)) * n_crown_taper + (1 - n_crown_taper))
randomize_amplitude = plant_height / 50
crown_segment_height = crown_height / height_segments_crown
for i in range(0, height_segments_crown - 1):
points = circle(
(0.0, 0.0, trunk_height + (i + 1) * crown_segment_height),
crown_diameter * crown_diameters[i] / 2,
res,
)
for i in range(0, len(points)):
points[i] = rand_add(points[i], randomize_amplitude)
verts.append(points)
# Top
verts.append(circle((0.0, 0.0, plant_height), 0.05, res))
edge_loops = []
for i in range(height_segments_total):
edge_loops.append(range(i * res, (i + 1) * res))
verts = merge_lists(verts)
faces = []
bottom = [*edge_loops[0]]
faces.append(bottom)
for i in range(height_segments_total - 1):
for j in range(res):
face = (edge_loops[i][j - 1], edge_loops[i][j], edge_loops[i + 1][j], edge_loops[i + 1][j - 1])
faces.append(face)
top = [*edge_loops[-1]]
faces.append(top)
verts_3D = [verts]
faces_3D = [faces]
verts_2D = [
[
(-0.5865642428398132, 0.8647078275680542, 0.0),
(-0.7583824992179871, 0.6572927236557007, 0.0),
(-0.7234422564506531, 0.5865941047668457, 0.0),
(-0.8714070916175842, 0.46631893515586853, 0.0),
(-0.9203394055366516, 0.15792329609394073, 0.0),
(-0.6487269997596741, 0.11522211134433746, 0.0),
(-0.9273074269294739, 0.0903107076883316, 0.0),
(-0.9606701731681824, -0.2852219343185425, 0.0),
(-0.8060722351074219, -0.35055163502693176, 0.0),
(-0.8271104693412781, -0.4677186608314514, 0.0),
(-0.6899875998497009, -0.6695915460586548, 0.0),
(-0.6215555667877197, -0.6767659187316895, 0.0),
(-0.4315463900566101, -0.8824808597564697, 0.0),
(-0.30316293239593506, -0.9023936986923218, 0.0),
(-0.32218849658966064, -0.8037619590759277, 0.0),
(-0.21792533993721008, -0.9530860185623169, 0.0),
(0.36917445063591003, -0.877334475517273, 0.0),
(0.30831706523895264, -0.685136079788208, 0.0),
(0.4778200685977936, -0.8094909191131592, 0.0),
(0.9163193106651306, -0.368840754032135, 0.0),
(0.827597439289093, -0.29377281665802, 0.0),
(0.9478662610054016, -0.245104119181633, 0.0),
(0.9667968153953552, 0.08458180725574493, 0.0),
(0.7529001832008362, 0.05212751030921936, 0.0),
(0.9102436900138855, 0.19098728895187378, 0.0),
(0.8279229998588562, 0.5522171258926392, 0.0),
(0.6635335087776184, 0.6461355686187744, 0.0),
(0.5753684639930725, 0.8170149326324463, 0.0),
(0.3976244330406189, 0.8779193162918091, 0.0),
(0.18733686208724976, 0.7513588666915894, 0.0),
(0.338344544172287, 0.910933256149292, 0.0),
(-0.013130240142345428, 0.9798095226287842, 0.0),
(-0.18649885058403015, 0.9414206743240356, 0.0),
(-0.3193224370479584, 0.8835403919219971, 0.0),
]
]
edges_2D = []
faces_2D = []
verts_2D_new = []
for vert in verts_2D[0]:
verts_2D_new.append(XY_scale(vert, crown_diameter / 2))
range_of_verts = range(0, len(verts_2D[0]))
for i in range_of_verts:
edges_2D.append([range_of_verts[i - 1], i])
faces_2D.append(i)
verts_2D[0] = verts_2D_new
edges_2D = [edges_2D]
faces_2D = [[faces_2D]]
verts_2D = [Vector(v).to_2d() for v in verts_2D[0]]
shape_2d = builder.polyline(points=verts_2D, closed=True)
shape_3d = builder.polygonal_face_set(points=verts_3D[0], faces=faces_3D[0])
return GeneratedGeometry((shape_2d,), (shape_3d,))
def generate_simple_tree(
builder: ShapeBuilder, plant_height=2, crown_diameter=2, trunk_diameter=0.1
) -> GeneratedGeometry:
unit_conversion = 1 / ifcopenshell.util.unit.calculate_unit_scale(builder.file)
plant_height *= unit_conversion
crown_diameter *= unit_conversion
trunk_diameter *= unit_conversion
crown_radius = crown_diameter / 2
# 3d shape
trunk_base = builder.circle(radius=trunk_diameter / 2)
trunk = builder.extrude(trunk_base, magnitude=plant_height - crown_diameter)
crown_position = (0.0, 0.0, (plant_height - crown_radius))
crown = builder.sphere(radius=crown_radius, center=crown_position)
# 2d shape
shape_2D = builder.circle(radius=crown_radius)
return GeneratedGeometry((shape_2D,), (trunk, crown))
def generate_palm_tree(
builder: ShapeBuilder, plant_height=2, crown_diameter=5.8, trunk_diameter=0.1
) -> GeneratedGeometry:
unit_conversion = 1 / ifcopenshell.util.unit.calculate_unit_scale(builder.file)
palm_verts = [
Vector((-3.6415634155273438, -3.8275668621063232, -1.0948246717453003)),
Vector((-0.3698049783706665, -1.805966854095459, 0.493910551071167)),
Vector((-1.6397790908813477, -0.5056067705154419, 0.04353363811969757)),
Vector((0.0, 0.0, 0.0)),
Vector((5.023162364959717, -1.6531240940093994, -1.0948246717453003)),
Vector((1.8090602159500122, 0.4589407444000244, 0.493910551071167)),
Vector((1.1666079759597778, -1.2413609027862549, 0.04353363811969757)),
Vector((1.6942416429519653, 5.038582801818848, -1.0948246717453003)),
Vector((-0.43215513229370117, 1.833944320678711, 0.493910551071167)),
Vector((1.2652605772018433, 1.1839056015014648, 0.04353363811969757)),
Vector((-4.577561378479004, 2.689336061477661, -1.0948246717453003)),
Vector((-1.8646581172943115, -0.0367276668548584, 0.493910551071167)),
Vector((-0.8873085975646973, 1.4957730770111084, 0.04353363811969757)),
]
palm_faces = [(2, 1, 0), (2, 3, 1), (6, 5, 4), (6, 3, 5), (9, 8, 7), (9, 3, 8), (12, 11, 10), (12, 3, 11)]
# each segment starts with the last point from the previous
palm_segments_2d_ifc = [(3, 11, 10, 12, 3), (3, 1, 0, 2, 3), (3, 5, 4, 6, 3), (3, 8, 7, 9, 3)]
palm_segments_2d_ifc = [[i + 1 for i in segment] for segment in palm_segments_2d_ifc] # IFC indices start with 1
scale = Vector()
scale.xyz = crown_diameter / 11.6
leaves_height = 0.493910551071167 * scale.z
plant_height -= leaves_height
for v in palm_verts:
v *= scale
v.z += plant_height
v *= unit_conversion
plant_height *= unit_conversion
crown_diameter *= unit_conversion
trunk_diameter *= unit_conversion
# 3d
leaves = builder.polygonal_face_set(palm_verts, palm_faces)
trunk_base = builder.circle(radius=trunk_diameter / 2)
trunk = builder.extrude(trunk_base, magnitude=plant_height)
# 2d
remove_z = Vector((1, 1, 0))
verts_2D = [v * remove_z for v in palm_verts]
ifc_points = builder.file.createIfcCartesianPointList2D(verts_2D)
ifc_segments = []
for segment in palm_segments_2d_ifc:
ifc_segments.append(builder.file.createIfcLineIndex(segment))
shape_2d = builder.file.createIfcIndexedPolyCurve(Points=ifc_points, Segments=ifc_segments)
return GeneratedGeometry((shape_2d,), (leaves, trunk))
tree_presets = {
"simple": TreePresetData(SimpleTreeParams, generate_simple_tree),
"low_poly": TreePresetData(LowPolyTreeParams, generate_low_poly_tree),
"palm_tree": TreePresetData(PalmTreeParams, generate_palm_tree),
}
class LibraryGenerator:
def generate(self, library_name, output_filename="IFC4 EU Steel.ifc"):
ifcopenshell.api.pre_listeners = {}
ifcopenshell.api.post_listeners = {}
self.materials = {}
self.file = ifcopenshell.api.run("project.create_file")
self.project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject", name=library_name)
self.library = ifcopenshell.api.run(
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=library_name
)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definition=self.library, relating_context=self.project
)
unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI")
ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit])
model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model")
plan = ifcopenshell.api.run("context.add_context", self.file, context_type="Plan")
self.representations = {
"model_body": ifcopenshell.api.run(
"context.add_context",
self.file,
context_type="Model",
context_identifier="Body",
target_view="MODEL_VIEW",
parent=model,
),
"plan_body": ifcopenshell.api.run(
"context.add_context",
self.file,
context_type="Plan",
context_identifier="Body",
target_view="PLAN_VIEW",
parent=plan,
),
}
self.builder = ShapeBuilder(self.file)
builder = self.builder
TreeData = namedtuple("TreeData", "tree_name preset_name preset_data")
trees = [
TreeData("Cone Tree (1.8m)", "low_poly", (1.8, 1.13, 0.0, 1.0, 0.28, 0.16, 10)),
TreeData("Cone Tree (15m)", "low_poly", (15.0, 4.37, 0.0, 1.0, 0.74, 0.44, 10)),
TreeData("Cone Tree (5m)", "low_poly", (5.0, 1.7, 0.0, 1.0, 0.32, 0.22, 10)),
TreeData("Hedge Small (0.4m)", "low_poly", (0.4, 0.4, 0.49, 0.15, 0.0, 0.0, 10)),
TreeData("Hedge Medium (0.8m)", "low_poly", (0.8, 0.8, 0.49, 0.15, 0.0, 0.0, 10)),
TreeData("Hedge Big (1.8m)", "low_poly", (1.8, 1.8, 0.49, 0.15, 0.0, 0.0, 10)),
TreeData("Palm Tree (5m)", "palm_tree", (5.0, 8.02, 0.2)),
TreeData("Palm Tree (15m)", "palm_tree", (15.0, 16.64, 0.4)),
TreeData("Shrub Small (0.4m)", "low_poly", (0.4, 0.4, 0.535, 0.524, 0.0, 0.0, 10)),
TreeData("Shrum Medium (0.8m)", "low_poly", (0.8, 0.8, 0.535, 0.524, 0.0, 0.0, 10)),
TreeData("Shrub Big (1.8m)", "low_poly", (1.8, 1.8, 0.535, 0.524, 0.0, 0.0, 10)),
TreeData("Simple Tree (1.8m)", "simple", (1.8, 1.34, 0.2)),
TreeData("Simple Tree (5m)", "simple", (5.0, 3.29, 0.2)),
TreeData("Simple Tree (15m)", "simple", (15.0, 9.21, 0.44)),
TreeData("Tree Small (1.8m)", "low_poly", (1.8, 1.7, 0.5, 0.36, 0.28, 0.16, 10)),
TreeData("Tree Big (15m)", "low_poly", (15.0, 10.0, 0.5, 0.36, 1.83, 0.44, 10)),
TreeData("Tree Medium (5m)", "low_poly", (5.0, 5.0, 0.5, 0.36, 0.84, 0.22, 10)),
]
for tree_data in trees:
preset = tree_presets.get(tree_data.preset_name)
preset_data = preset.preset_class(*tree_data.preset_data)._asdict()
tree_geometry = preset.generator(builder, **preset_data)
self.create_explicit_type(
"IfcGeographicElementType", tree_data.tree_name, **self.get_representations(tree_geometry)
)
self.file.write(output_filename)
def get_representations(self, generated_geometry: GeneratedGeometry):
representation_2d = self.builder.get_representation(
self.representations["plan_body"], items=generated_geometry.items_2d
)
representation_3d = self.builder.get_representation(
self.representations["model_body"], items=generated_geometry.items_3d
)
return {
"representation_3d": representation_3d,
"representation_2d": representation_2d,
}
def create_explicit_type(self, ifc_class, name, representation_3d, representation_2d, **params):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name)
for param, value in params.items():
setattr(element, param, value)
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation_3d
)
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation_2d
)
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
return element
if __name__ == "__main__":
path = Path(__file__).parents[1] / "blenderbim/bim/data/libraries"
LibraryGenerator().generate("Landscape Assets Library", output_filename=str(path / "IFC4 Landscape Library.ifc"))
+97
View File
@@ -575,3 +575,100 @@ class TestGetIfcRepresentationClass(NewFile):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
assert subject.get_ifc_representation_class(ifc.createIfcColumn(), ifc.createIfcShapeRepresentation()) is None
class TestRemoveRepresentationItem(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
context = ifc.createIfcGeometricRepresentationContext()
element = ifc.createIfcWall()
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context)
tool.Ifc.run("geometry.assign_representation", product=element, representation=representation)
product_shape = element.Representation
shape_aspect = subject.create_shape_aspect(product_shape, representation, items[:1], None)
shape_aspect_id = shape_aspect.id()
subject.remove_representation_item(items[0])
assert tool.Ifc.get_entity_by_id(shape_aspect_id) is None
assert set(representation.Items) == {items[1]}
class TestCreateShapeAspect(NewFile):
def test_run(self):
self.create_shape_aspect(use_element_type=False)
self.create_shape_aspect(use_element_type=True)
def create_shape_aspect(self, use_element_type):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
context = ifc.createIfcGeometricRepresentationContext()
element = ifc.createIfcWallType() if use_element_type else ifc.createIfcWall()
item = ifc.createIfcExtrudedAreaSolid()
items = [item]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context)
tool.Ifc.run("geometry.assign_representation", product=element, representation=representation)
product_shape = element.RepresentationMaps[0] if use_element_type else element.Representation
subject.create_shape_aspect(product_shape, representation, items, None)
assert len(product_shape.HasShapeAspects) == 1
representation = product_shape.HasShapeAspects[0].ShapeRepresentations[0]
assert set(representation.Items) == set(items)
class TestAddRepresentationItemToShapeAspect(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
context = ifc.createIfcGeometricRepresentationContext()
element = ifc.createIfcWall()
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context)
tool.Ifc.run("geometry.assign_representation", product=element, representation=representation)
product_shape = element.Representation
shape_aspect0 = subject.create_shape_aspect(product_shape, representation, [items[0]], None)
previous_shape_aspect_id = shape_aspect0.id()
shape_aspect1 = subject.create_shape_aspect(product_shape, representation, [items[1]], None)
subject.add_representation_item_to_shape_aspect([items[0]], shape_aspect1)
# previous shape aspect removed as there won't be any items in it
assert tool.Ifc.get_entity_by_id(previous_shape_aspect_id) is None
representation = shape_aspect1.ShapeRepresentations[0]
assert set(representation.Items) == set(items)
class TestRemoveRepresentationItemFromShapeAspect(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
context = ifc.createIfcGeometricRepresentationContext()
element = ifc.createIfcWall()
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context)
tool.Ifc.run("geometry.assign_representation", product=element, representation=representation)
product_shape = element.Representation
shape_aspect0 = subject.create_shape_aspect(product_shape, representation, [items[0]], None)
previous_shape_aspect_id = shape_aspect0.id()
previous_shape_aspect_rep_id = shape_aspect0.ShapeRepresentations[0].id()
shape_aspect1 = subject.create_shape_aspect(product_shape, representation, [items[1]], None)
subject.remove_representation_items_from_shape_aspect([items[0]], shape_aspect0)
# previous shape aspect and representation are removed as there won't be any items in them
assert tool.Ifc.get_entity_by_id(previous_shape_aspect_id) is None
assert tool.Ifc.get_entity_by_id(previous_shape_aspect_rep_id) is None
# items is removed from the representaiton
subject.add_representation_item_to_shape_aspect([items[0]], shape_aspect1)
subject.remove_representation_items_from_shape_aspect([items[1]], shape_aspect1)
representation = shape_aspect1.ShapeRepresentations[0]
assert set(representation.Items) == {items[0]}
+67 -49
View File
@@ -21,6 +21,7 @@ import ifcopenshell
import blenderbim.core.tool
import blenderbim.tool as tool
import numpy as np
import json
from test.bim.bootstrap import NewFile
from blenderbim.tool.model import Model as subject
from ifcopenshell.util.shape_builder import V
@@ -54,58 +55,75 @@ class TestGenerateOccurrenceName(NewFile):
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Foobar"
class TestGetManualBooleans(NewFile):
def test_get_manual_booleans(self):
clippings = [
{
"type": "IfcBooleanClippingResult",
"operand_type": "IfcHalfSpaceSolid",
"matrix": np.eye(4).tolist(),
},
{
"type": "IfcBooleanResult",
"operand_type": "IfcHalfSpaceSolid",
"matrix": np.eye(4).tolist(),
},
]
class TestGetBooleans(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
self.ifc = ifc
tool.Ifc.set(ifc)
ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject")
length = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="LENGTHUNIT")
ifcopenshell.api.run("unit.assign_unit", ifc, units=[length])
ifcopenshell.api.run("unit.assign_unit", ifc)
element = ifc.createIfcColumn()
hea100 = ifc.create_entity(
"IfcIShapeProfileDef",
ProfileName="HEA100",
ProfileType="AREA",
OverallWidth=100,
OverallDepth=96,
WebThickness=5,
FlangeThickness=8,
FilletRadius=12,
)
model3d = ifcopenshell.api.run("context.add_context", ifc, context_type="Model")
body = ifcopenshell.api.run(
"context.add_context",
ifc,
context_type="Model",
context_identifier="Body",
target_view="MODEL_VIEW",
parent=model3d,
)
representation = ifcopenshell.api.run(
"geometry.add_profile_representation", ifc, context=body, profile=hea100, depth=5, clippings=clippings
)
ifcopenshell.api.run("geometry.assign_representation", ifc, product=element, representation=representation)
booleans = subject.get_booleans(element)
assert len(booleans) == 2
assert len(subject.get_manual_booleans(element)) == 0
subject.mark_manual_booleans(element, booleans)
assert len(subject.get_manual_booleans(element)) == 2
context = ifc.createIfcGeometricRepresentationContext()
element = ifc.createIfcWall()
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context)
tool.Ifc.run("geometry.assign_representation", product=element, representation=representation)
bool1 = set(tool.Ifc.run("geometry.add_boolean", representation=representation, matrix=np.eye(4)))
bool2 = set(tool.Ifc.run("geometry.add_boolean", representation=representation, matrix=np.eye(4)))
assert set(subject.get_booleans(element, representation)) == bool1 | bool2
class TestGetManualBooleans(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
context = ifc.createIfcGeometricRepresentationContext()
element = ifc.createIfcWall()
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context)
tool.Ifc.run("geometry.assign_representation", product=element, representation=representation)
bool1 = set(tool.Ifc.run("geometry.add_boolean", representation=representation, matrix=np.eye(4)))
bool2 = set(tool.Ifc.run("geometry.add_boolean", representation=representation, matrix=np.eye(4)))
assert set(subject.get_booleans(element, representation)) == bool1 | bool2
assert len(subject.get_manual_booleans(element, representation)) == 0
subject.mark_manual_booleans(element, bool1)
assert set(subject.get_manual_booleans(element, representation)) == bool1
class TestMarkManualBooleans(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
element = ifc.createIfcWall()
boolean = ifc.createIfcBooleanClippingResult()
subject.mark_manual_booleans(element, [boolean])
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
assert pset
value = json.loads(pset["Data"])
assert set(value) == {boolean.id()}
class TestUnmarkManualBooleans(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
element = ifc.createIfcWall()
boolean = ifc.createIfcBooleanClippingResult()
boolean2 = ifc.createIfcBooleanClippingResult()
subject.mark_manual_booleans(element, [boolean, boolean2])
subject.unmark_manual_booleans(element, [boolean.id()])
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
assert pset
value = json.loads(pset["Data"])
assert set(value) == {boolean2.id()}
class TestStairCalculatedParams(NewFile):
+36 -2
View File
@@ -23,6 +23,7 @@ import blenderbim.core.tool
import blenderbim.tool as tool
from test.bim.bootstrap import NewFile
from blenderbim.tool.style import Style as subject
from ifcopenshell.util.shape_builder import ShapeBuilder
class TestImplementsTool(NewFile):
@@ -166,7 +167,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
obj.node_tree.nodes.remove(node)
node = obj.node_tree.nodes.new(type="ShaderNodeBsdfGlossy")
node.inputs["Color"].default_value = [0.5, 0.5, 0.5, 0.5]
node.inputs["Roughness"].default_value = 0.2
@@ -197,7 +198,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
obj.node_tree.nodes.remove(node)
node = obj.node_tree.nodes.new(type="ShaderNodeBsdfDiffuse")
node.inputs["Color"].default_value = [0.5, 0.5, 0.5, 0.5]
node.inputs["Roughness"].default_value = 0.2
@@ -460,3 +461,36 @@ class TestIsEditingStyles(NewFile):
subject.is_editing_styles() is False
bpy.context.scene.BIMStylesProperties.is_editing = True
subject.is_editing_styles() is True
class TestGetRepresentationStyleItem(NewFile):
def test_run(self):
tool.Ifc.set(ifc := ifcopenshell.file())
builder = ShapeBuilder(ifc)
rectangle = builder.rectangle()
assert subject.get_representation_item_style(rectangle) == None
style = ifc.createIfcSurfaceStyle()
subject.assign_style_to_representation_item(rectangle, style)
assert subject.get_representation_item_style(rectangle) == style
class TestAssignStyleToRepresentationItem(NewFile):
def test_run(self):
tool.Ifc.set(ifc := ifcopenshell.file())
builder = ShapeBuilder(ifc)
rectangle = builder.rectangle()
# assigning new style
style1 = ifc.createIfcSurfaceStyle()
subject.assign_style_to_representation_item(rectangle, style1)
assert subject.get_representation_item_style(rectangle) == style1
# changing style
style2 = ifc.createIfcSurfaceStyle()
subject.assign_style_to_representation_item(rectangle, style2)
assert subject.get_representation_item_style(rectangle) == style2
# unassigning styles
subject.assign_style_to_representation_item(rectangle, None)
assert subject.get_representation_item_style(rectangle) == None
+8
View File
@@ -34,6 +34,7 @@ import ifcopenshell.util.placement
import ifcopenshell.util.classification
import ifcopenshell.util.representation
from deepdiff import DeepDiff
from ordered_set import OrderedSet
class IfcDiff:
@@ -234,6 +235,12 @@ class IfcDiff:
settings.set_context_ids(body_contexts)
return settings
def json_dump_default(self, obj):
# result of DeepDiff may contain ordered sets
if isinstance(obj, (OrderedSet, set)):
return list(obj)
return json.JSONEncoder.default(None, obj)
def export(self, path):
with open(path, "w", encoding="utf-8") as diff_file:
json.dump(
@@ -244,6 +251,7 @@ class IfcDiff:
},
diff_file,
indent=4,
default=self.json_dump_default,
)
def get_precision(self):
@@ -21,6 +21,19 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
"""Remove a representation.
Also purges representation items and their related elements
like IfcStyledItem, tessellated facesets colours and UV map.
:param representation: IfcRepresentation to remove.
Note that it's expected that IfcRepresentation won't be in use
before calling this method (in such elements as IfcProductRepresentation, IfcShapeAspect)
otherwise representation won't be removed.
:type representation: ifcopenshell.entity_instance
:return: None
:rtype: None
"""
self.file = file
self.settings = {"representation": None}
for key, value in settings.items():
@@ -34,13 +47,13 @@ class Usecase:
for subelement in self.file.traverse(self.settings["representation"]):
if subelement.is_a("IfcRepresentationItem"):
[styled_items.add(s) for s in subelement.StyledByItem or []]
# IfcTesselatedFaceSet inverses
[presentation_layer_assignments.add(s) for s in subelement.LayerAssignment]
# IfcTessellatedFaceSet inverses
[textures.add(t) for t in getattr(subelement, "HasTextures", []) or []]
[colours.add(t) for t in getattr(subelement, "HasColours", []) or []]
elif subelement.is_a("IfcRepresentation"):
for inverse in self.file.get_inverse(subelement):
if inverse.is_a("IfcPresentationLayerAssignment"):
presentation_layer_assignments.add(inverse)
for layer in subelement.LayerAssignments:
presentation_layer_assignments.add(layer)
ifcopenshell.util.element.remove_deep2(
self.file,
@@ -54,7 +54,7 @@ class Usecase:
the work performed.
:type resource: ifcopenshell.entity_instance.entity_instance
:return None:
:rtype None:
:rtype: None:
"""
self.file = file
self.settings = {"resource": resource}
@@ -62,9 +62,7 @@ class Usecase:
def execute(self):
if ifcopenshell.util.constraint.is_attribute_locked(self.settings["resource"], "Usage.ScheduleWork"):
return
amount_worked = ifcopenshell.util.resource.get_resource_required_work(
self.settings["resource"]
)
amount_worked = ifcopenshell.util.resource.get_resource_required_work(self.settings["resource"])
if not amount_worked:
return
if not self.settings["resource"].Usage:
@@ -338,7 +338,7 @@ def get_type(element):
:param element: The element occurrence
:type: ifcopenshell.entity_instance.entity_instance
:return: The related type element
:rtype ifcopenshell.entity_instance.entity_instance
:rtype: ifcopenshell.entity_instance.entity_instance
Example:
@@ -817,8 +817,9 @@ def get_aggregate(element):
Example:
.. code:: python
element = file.by_type("IfcBeam")[0]
aggregate = ifcopenshell.util.element.get_aggregate(element)
element = file.by_type("IfcBeam")[0]
aggregate = ifcopenshell.util.element.get_aggregate(element)
"""
if hasattr(element, "Decomposes") and element.Decomposes:
if element.Decomposes[0].is_a("IfcRelAggregates"): # IFC2X3
@@ -835,8 +836,9 @@ def get_nest(element):
Example:
.. code:: python
element = file.by_type("IfcBeam")[0]
aggregate = ifcopenshell.util.element.get_nest(element)
element = file.by_type("IfcBeam")[0]
aggregate = ifcopenshell.util.element.get_nest(element)
"""
if hasattr(element, "Nests"):
if element.Nests:
@@ -856,9 +858,9 @@ def get_parts(element):
Example:
.. code:: python
element = file.by_type("IfcElementAssembly")[0]
parts = ifcopenshell.util.element.get_parts(element)
element = file.by_type("IfcElementAssembly")[0]
parts = ifcopenshell.util.element.get_parts(element)
"""
if hasattr(element, "IsDecomposedBy") and element.IsDecomposedBy:
if element.IsDecomposedBy[0].is_a("IfcRelAggregates"):
@@ -879,9 +881,9 @@ def get_components(element, include_ports=False):
Example:
.. code:: python
element = file.by_type("IfcElementAssembly")[0]
components = ifcopenshell.util.element.get_components(element)
element = file.by_type("IfcElementAssembly")[0]
components = ifcopenshell.util.element.get_components(element)
"""
if hasattr(element, "IsNestedBy"):
if element.IsNestedBy:
@@ -47,27 +47,44 @@ round_vector_to_precision = lambda v, si_conversion: Vector([round_to_precision(
class ShapeBuilder:
def __init__(self, ifc_file):
def __init__(self, ifc_file: ifcopenshell.file):
self.file = ifc_file
def polyline(
self, points: List[Vector], closed: bool = False, position_offset: Vector = None, arc_points: List[int] = []
):
) -> ifcopenshell.entity_instance:
"""
Generate an IfcIndexedPolyCurve based on the provided points.
:param points: List of points formatted as ( (x0, y0), (x1, y1) )
:type: List[Vector]
:param closed: Whether polyline should be closed. Default is False.
:type: bool, optional
:param position_offset: Optional offset to be applied to all points.
:type: Optional[Vector]
:param points: List of 2d or 3d points
:type points: List[Vector]
:param closed: Whether polyline should be closed. Default is `False`
:type closed: bool, optional
:param position_offset: offset to be applied to all points
:type position_offset: Vector, optional
:param arc_points: Indices of the middle points for arcs. For creating an arc segment,
provide 3 points: `arc_start`, `arc_middle` and `arc_end` and add the `arc_middle`
point's index to this list.
:type: List[int]
provide 3 points: `arc_start`, `arc_middle` and `arc_end` to `points` and add the `arc_middle`
point's index to `arc_points`
:type arc_points: List[int], optional
:return: IfcIndexedPolyCurve
:rtype: ifcopenshell.entity_instance
Example:
.. code:: python
# rectangle
points = Vector((0, 0)), Vector((1, 0)), Vector((1, 1)), Vector((0, 1))
position = Vector((2, 0))
# #2=IfcIndexedPolyCurve(#1,(IfcLineIndex((1,2,3,4,1))),$)
polyline = builder.polyline(points, closed=True, position_offset=position)
# arc between points (1,0) and (0,1). Second point in the arc should be it's middle
points = Vector((1, 0)), Vector((0.707, 0.707)), Vector((0, 1)), Vector((0,2))
arc_points = (1,) # point with index 1 is a middle of the arc
# 4=IfcIndexedPolyCurve(#3,(IfcArcIndex((1,2,3)),IfcLineIndex((3,4,1))),$)
curved_polyline = builder.polyline(points, closed=False, position_offset=position, arc_points=arc_points)
"""
if arc_points and self.file.schema == "IFC2X3":
@@ -130,9 +147,24 @@ class ShapeBuilder:
ifc_curve = self.file.createIfcIndexedPolyCurve(Points=ifc_points, Segments=ifc_segments)
return ifc_curve
def get_rectangle_coords(self, size: Vector = Vector((1.0, 1.0)).freeze(), position: Vector = None):
"""get rectangle coords in counter-clockwise order
starting from the bottom left corner"""
def get_rectangle_coords(self, size: Vector = Vector((1.0, 1.0)).freeze(), position: Vector = None) -> List[Vector]:
"""
Get rectangle coords arranged as below:
::
3 2
0 1
:param size: rectangle size, could be either 2d or 3d, defaults to `(1,1)`
:type size: Vector, optional
:param position: rectangle position, default to `None`.
if `position` not specified zero-vector will be used
:type position: Vector, optional
:return: list of rectangle coords
:rtype: List[Vector]
"""
dimensions = len(size)
if not position:
@@ -150,22 +182,33 @@ class ShapeBuilder:
]
return points
def rectangle(self, size: Vector = Vector((1.0, 1.0)).freeze(), position: Vector = None):
def rectangle(
self, size: Vector = Vector((1.0, 1.0)).freeze(), position: Vector = None
) -> ifcopenshell.entity_instance:
"""
Generate a rectangle polyline, method supports both 2d and 3d rectangle sizes.
Generate a rectangle polyline.
:param size: rectangle size
:param type: Vector
:param size: rectangle position, default to `None`.
if `position` not specified zero-vector will be used
:param type: Vector, optional
:param size: rectangle size, could be either 2d or 3d, defaults to `(1,1)`
:type size: Vector, optional
:param position: rectangle position, default to `None`.
if `position` not specified zero-vector will be used
:type position: Vector, optional
:return: IfcIndexedPolyCurve
:rtype: ifcopenshell.entity_instance
"""
return self.polyline(self.get_rectangle_coords(size, position), closed=True)
def circle(self, center: Vector = Vector((0.0, 0.0)).freeze(), radius=1.0):
# < returns IfcCircle
def circle(self, center: Vector = Vector((0.0, 0.0)).freeze(), radius: float = 1.0) -> ifcopenshell.entity_instance:
"""
:param center: circle 2D position, defaults to zero-vector
:type center: Vector, optional
:param radius: radius of the circle, defaults to 1.0
:type radius: float, optional
:return: IfcCircle
:rtype: ifcopenshell.entity_instance
"""
ifc_center = self.file.createIfcAxis2Placement2D(self.file.createIfcCartesianPoint(center))
ifc_curve = self.file.createIfcCircle(ifc_center, radius)
@@ -556,6 +599,24 @@ class ShapeBuilder:
return processed_objects if (multiple_objects or multiple_transformations) else processed_objects[0]
def sphere(self, radius: float = 1.0, center: Vector = Vector((0, 0, 0)).freeze()) -> ifcopenshell.entity_instance:
"""
:param radius: radius of the sphere, defaults to 1.0
:type radius: float, optional
:param center: sphere position, defaults to zero-vector
:type center: Vector, optional
:return: IfcSphere
:rtype: ifcopenshell.entity_instance
"""
ifc_position = self.file.createIfcAxis2Placement3D(
self.file.createIfcCartesianPoint(center), # position
self.file.createIfcDirection((0.0, 0.0, 1.0)), # Z-axis / Axis
self.file.createIfcDirection((1.0, 0.0, 0.0)), # X-axis / RefDirection
)
return self.file.createIfcSphere(Radius=radius, Position=ifc_position)
def extrude(
self,
profile_or_curve,
@@ -616,16 +677,17 @@ class ShapeBuilder:
disk_solid = self.file.createIfcSweptDiskSolid(Directrix=path_curve, Radius=radius)
return disk_solid
def get_representation(self, context, items, representation_type: str = None):
def get_representation(self, context, items, representation_type: str = None) -> ifcopenshell.entity_instance:
"""Create IFC representation for the specified context and items.
:param context: IfcGeometricRepresentationSubContext
:param items: could be a list or single curve/IfcExtrudedAreaSolid
:param representation_type: Explicitly specified RepresentationType, defaults to `None`.
If not provided it will be guessed from the items types.
If not provided it will be guessed from the items types
:type representation_type: str, optional
:return: IfcRepresentation
:rtype: ifcopenshell.entity_instance
"""
if not isinstance(items, collections.abc.Iterable):
items = [items]
@@ -726,7 +788,7 @@ class ShapeBuilder:
> coords: list of 2d coords. Example: ((x0,y0), (x1,y1), (x2, y2))
> fillets: list of points from `coords` to base fillet on. Example: (1,)
> fillet_radius: list of fillet radius for each of corresponding point form `fillets`. Example: (5.,)
Note: filler_radius could be just 1 float value if it's the same for all fillets.
Note: filler_radius could be just 1 float value if it's the same for all fillets.
Optional arguments:
> closed: boolean whether curve should be closed (whether last point connected to first one). Default: True
@@ -1335,23 +1397,23 @@ class ShapeBuilder:
radius: float,
bend_vector: Vector,
flip_z_axis: bool,
):
) -> ifcopenshell.entity_instance:
"""
:param segment: IfcFlowSegment for a bend.
Note that for a bend start and end segments types should match.
Note that for a bend start and end segments types should match.
:type segment: ifcopenshell.entity_instance
:param angle: bend angle, in radians
:param type: float
:type angle: float
:param radius: bend radius
:param type: float
:type radius: float
:param bend_vector: offset between start and end segments in local space of start segment
used mainly to determine the second bend axis and it's direction (positive or negative),
the actual magnitude of the vector is not important (though near zero values will be ignored).
:param type: Vector
:type bend_vector: Vector
:param flip_z_axis: since we cannot determine z axis direction from the profile offset,
there is an option to flip it if bend is going by start segment Z- axis.
:param type: bool
there is an option to flip it if bend is going by start segment Z- axis.
:type flip_z_axis: bool
:return: tuple of Model/Body/MODEL_VIEW IfcRepresentation and transition shape data
"""
@@ -79,14 +79,14 @@ class TestRemoveRepresentation(test.bootstrap.IFC4):
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=representation)
assert len(self.file.by_type("IfcStyledItem")) == 1
def test_purging_presentation_layers(self):
def test_purging_representation_presentation_layers(self):
representation = self.file.createIfcShapeRepresentation()
layer = self.file.createIfcPresentationLayerAssignment(AssignedItems=[representation])
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=representation)
assert len(self.file.by_type("IfcPresentationLayerAssignment")) == 0
assert len(self.file.by_type("IfcShapeRepresentation")) == 0
def test_not_purging_presentation_layers_still_in_use(self):
def test_not_purging_representation_presentation_layers_still_in_use(self):
representation = self.file.createIfcShapeRepresentation()
representation2 = self.file.createIfcShapeRepresentation()
layer = self.file.createIfcPresentationLayerAssignment(AssignedItems=[representation, representation2])
@@ -94,6 +94,23 @@ class TestRemoveRepresentation(test.bootstrap.IFC4):
assert len(self.file.by_type("IfcPresentationLayerAssignment")) == 1
assert len(self.file.by_type("IfcShapeRepresentation")) == 1
def test_purging_representation_item_presentation_layers(self):
item = self.file.createIfcExtrudedAreaSolid()
representation = self.file.createIfcShapeRepresentation(Items=[item])
layer = self.file.createIfcPresentationLayerAssignment(AssignedItems=[item])
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=representation)
assert len(self.file.by_type("IfcPresentationLayerAssignment")) == 0
assert len(self.file.by_type("IfcExtrudedAreaSolid")) == 0
def test_not_purging_representation_item_presentation_layers_still_in_use(self):
item, item2 = self.file.createIfcExtrudedAreaSolid(), self.file.createIfcExtrudedAreaSolid()
representation = self.file.createIfcShapeRepresentation(Items=[item])
representation2 = self.file.createIfcShapeRepresentation(Items=[item2])
layer = self.file.createIfcPresentationLayerAssignment(AssignedItems=[item, item2])
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=representation)
assert len(self.file.by_type("IfcPresentationLayerAssignment")) == 1
assert len(self.file.by_type("IfcExtrudedAreaSolid")) == 1
def test_not_purging_geometric_representation_contexts(self):
context = self.file.createIfcGeometricRepresentationSubContext()
representation = self.file.createIfcShapeRepresentation(ContextOfItems=context)
@@ -19,11 +19,50 @@
import pytest
import test.bootstrap
import ifcopenshell.api
import numpy as np
from ifcopenshell.util.shape_builder import ShapeBuilder, V, is_x
from math import degrees, radians, tan
from mathutils import Vector
class TestCreatePolyline(test.bootstrap.IFC4):
def test_simple_polyline(self):
builder = ShapeBuilder(self.file)
# rectangle
points = Vector((0, 0)), Vector((1, 0)), Vector((1, 1)), Vector((0, 1))
position = Vector((2, 0))
polyline = builder.polyline(points, closed=True, position_offset=position)
points = [p + position for p in points]
assert np.allclose(np.array(points), np.array(polyline.Points.CoordList))
# use 1 line index if there are no arcs
assert len(polyline.Segments) == 1
segment = polyline.Segments[0]
assert segment.is_a("IfcLineIndex")
assert segment.wrappedValue == (1, 2, 3, 4, 1)
def test_polyline_with_arc(self):
builder = ShapeBuilder(self.file)
points = Vector((1, 0)), Vector((0.707, 0.707)), Vector((0, 1)), Vector((0, 2))
position = Vector((2, 0))
arc_points = (1,)
# 4=IfcIndexedPolyCurve(#3,(IfcArcIndex((1,2,3)),IfcLineIndex((3,4,1))),$)
polyline = builder.polyline(points, closed=False, position_offset=position, arc_points=arc_points)
points = [p + position for p in points]
assert np.allclose(np.array(points), np.array(polyline.Points.CoordList))
assert len(polyline.Segments) == 2
segment = polyline.Segments[0]
assert segment.is_a("IfcArcIndex")
assert segment.wrappedValue == (1, 2, 3)
segment = polyline.Segments[1]
assert segment.is_a("IfcLineIndex")
assert segment.wrappedValue == (3, 4)
class TestCalculateTransitions(test.bootstrap.IFC4):
def calculate_and_test(self, params, length):
end_profile = params["end_profile"]