Compare commits
1625 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1eef746f60 | |||
| 1696ca5e08 | |||
| c011458ea2 | |||
| abf809f9dd | |||
| 9257816e62 | |||
| d47125b28f | |||
| b7453f584e | |||
| 9c4fa666c9 | |||
| a970120fac | |||
| 72907cd3f0 | |||
| ae7c9f35a6 | |||
| 0b111084b0 | |||
| 2ee0dcaf64 | |||
| 70eabead92 | |||
| 5a30d9fb9b | |||
| 3126db342d | |||
| c0db03438f | |||
| 1542217117 | |||
| 5b4010c67d | |||
| c18d96f0e3 | |||
| f9173700a6 | |||
| 7100a7fa8e | |||
| 0078d691d3 | |||
| fd626e37a0 | |||
| e62d7ad9ef | |||
| 80eebc03d3 | |||
| 62fea990d9 | |||
| 7ab01e6ac0 | |||
| 74a025b81c | |||
| ca8ed87f2a | |||
| 9fbcb3900f | |||
| 1533283822 | |||
| 6beca6382f | |||
| a1caef5b4f | |||
| 7da96b4951 | |||
| 66c275f617 | |||
| 52a8fcd86e | |||
| 3ba7ecdb95 | |||
| 36f7625cee | |||
| ee82714423 | |||
| 281147367e | |||
| 0beea4255a | |||
| b03c4da7bf | |||
| c0402687b5 | |||
| c6fa7161b6 | |||
| 64516a173a | |||
| f507e3e8bd | |||
| 2f15d73b30 | |||
| 53cc6f0bd6 | |||
| 7680652c28 | |||
| e8b1d00e6d | |||
| 6ec7e48423 | |||
| ccf09b962a | |||
| 485d41ae09 | |||
| b67c5a0828 | |||
| 7b92057227 | |||
| a980ce1bfa | |||
| 51b7f24a00 | |||
| 136e1c3b3f | |||
| c094517a10 | |||
| b61a11d5b7 | |||
| 012da8fcb9 | |||
| d64c1358d7 | |||
| 0252701f7a | |||
| 6fed9bf795 | |||
| b088a763d8 | |||
| 104fe56612 | |||
| 9e0760b8d2 | |||
| f26986645a | |||
| a86456392b | |||
| 61de0ad64c | |||
| 243eee9ebf | |||
| f23ac034c7 | |||
| 363ede9801 | |||
| 18d26df24e | |||
| 0df62d5746 | |||
| f5031035c7 | |||
| fc50bdd3a0 | |||
| 3117d5b2e7 | |||
| e6dc1d1acd | |||
| bd8afabce3 | |||
| 01da8498f2 | |||
| a34b8d06ec | |||
| 5764cfcbb9 | |||
| 1ad2465ad4 | |||
| f28e28abc0 | |||
| 97e321dd12 | |||
| fc4b36e759 | |||
| 832cdce934 | |||
| e45974df62 | |||
| bba118ed19 | |||
| 709590401c | |||
| ab74d1456b | |||
| 4457da9042 | |||
| d501118eb4 | |||
| 0a03d20133 | |||
| f3f56c0891 | |||
| a689b31279 | |||
| 4d0be19720 | |||
| fb7591caef | |||
| 8efaf2fbcb | |||
| d41068e132 | |||
| 4e65f143da | |||
| 40656297a6 | |||
| f88835b87b | |||
| 8f18db64cf | |||
| fdd473234a | |||
| 569f56f713 | |||
| 61607f9de2 | |||
| 40b34f6a33 | |||
| 89b0674b08 | |||
| 37e4f98857 | |||
| e89a9cd01c | |||
| 20b63f530a | |||
| 183230b7f5 | |||
| 7e2b40176c | |||
| 3aff29dec1 | |||
| 2ce32c6521 | |||
| 9d84172f15 | |||
| 8341931a62 | |||
| 81a4ff711c | |||
| 2da86c170f | |||
| 41a176cb6d | |||
| 10e96239a1 | |||
| 897dfb1e33 | |||
| c1d972f7bf | |||
| d9196882dc | |||
| 580f8f6218 | |||
| e177f5f051 | |||
| 1a5c501af0 | |||
| 12c10f98a3 | |||
| e3a7f76276 | |||
| 046ce2b8e7 | |||
| 6dab4501ad | |||
| 2dc9dc2000 | |||
| addce9f0ea | |||
| 4a368938c3 | |||
| a0f68baefc | |||
| 3decb48ed0 | |||
| 2d330f4c90 | |||
| 1c996013b6 | |||
| 65cb47e2d8 | |||
| e9d0b8ab66 | |||
| 0bb9bcd9fb | |||
| 997ebe48df | |||
| 0cdf72fde1 | |||
| 97c6b99d57 | |||
| ed5d28de54 | |||
| f5c102402f | |||
| 7aa04611a1 | |||
| 5c7f14cc3c | |||
| 9e1249d8ee | |||
| 6cb7234cb5 | |||
| aab6a21bf3 | |||
| c72f960ed4 | |||
| b63b4ce326 | |||
| 71113b56bf | |||
| ef57c209a0 | |||
| e99c154cb2 | |||
| 520860bdb9 | |||
| 103e8a545b | |||
| d35c5c433f | |||
| 7dc98612e4 | |||
| 3853258b27 | |||
| 6825d26700 | |||
| 900c35e9fe | |||
| 7aafa87b52 | |||
| e719055d9a | |||
| a956038bfc | |||
| 5c2ae98c09 | |||
| 99d9c0f5bf | |||
| 2fbb9c569b | |||
| 4a9d1ff038 | |||
| bcf5f07718 | |||
| a3572f3372 | |||
| 6cd9161986 | |||
| 982f4a4965 | |||
| c5aab16696 | |||
| 6e1b18ba33 | |||
| 2b3d547c99 | |||
| a34be6ae5d | |||
| dfc5a280a4 | |||
| 6a2bbfa85c | |||
| ddef4820d0 | |||
| e6b05b547b | |||
| 5e8ec48d98 | |||
| 9c21304629 | |||
| 1278f98df6 | |||
| d31b470e83 | |||
| 1ecb25684e | |||
| 5999976d37 | |||
| 51e5f843ba | |||
| 3d787338fb | |||
| de67648f3e | |||
| afa803ea62 | |||
| 3a0aaee03b | |||
| a5353e02b5 | |||
| 1acc743370 | |||
| 375f4f2a86 | |||
| d4b88fd422 | |||
| df6cc74a87 | |||
| 80846061f2 | |||
| 80f9590410 | |||
| 16cda28d16 | |||
| 24ea024a0d | |||
| e90d7ccdb1 | |||
| 1a3bf513a7 | |||
| a855c40426 | |||
| c8ede38edb | |||
| 704e27ecca | |||
| 438ddc17f5 | |||
| a8dfed50e4 | |||
| 8cb99a77cf | |||
| f9b6e6f098 | |||
| 1365b76149 | |||
| 47cc3158fd | |||
| bac683e105 | |||
| 840818d681 | |||
| 206933a2f2 | |||
| ff209b4c11 | |||
| 4bc987924d | |||
| f26cfc93ea | |||
| 4bbb6cd2df | |||
| 9411a1d94b | |||
| 6a287ced7c | |||
| fb02ac34d4 | |||
| 81fd84223a | |||
| a8f1a28ac2 | |||
| d2f4f0d8c2 | |||
| 1c17cccc45 | |||
| 061930bc8e | |||
| 28cc168b3b | |||
| 88f53f7931 | |||
| 755fa81817 | |||
| 36fab12847 | |||
| 32393136d2 | |||
| c7b3331496 | |||
| 7c0c934b4f | |||
| 62944e04e9 | |||
| 3a93b15b55 | |||
| 83cd00271b | |||
| 820686a39b | |||
| 4fe896a3b6 | |||
| 975b1c444c | |||
| c3f2046491 | |||
| 3a1557bedc | |||
| a71b5e1f11 | |||
| 4806b9a260 | |||
| 0d67c43e16 | |||
| e2b52e7ed9 | |||
| 3c53067567 | |||
| 5ad7d4bb2a | |||
| 3803942c5f | |||
| 678f50f17d | |||
| 04fe2bdf2e | |||
| ed990c3e83 | |||
| 741c78cd6c | |||
| 2b88c542aa | |||
| 1f6b55e639 | |||
| 9f3fb13cde | |||
| 42f1d9c160 | |||
| f0875835c1 | |||
| 0828a89b66 | |||
| a8ca66b425 | |||
| 92b03c6b59 | |||
| d316efe902 | |||
| 77e4e939ce | |||
| fe7504edf2 | |||
| a8f1ab1923 | |||
| 1b5f9497d4 | |||
| a7bbb35c5e | |||
| 1787f064f6 | |||
| d1c24ebba4 | |||
| cc6dacb286 | |||
| c67eb60fd5 | |||
| 59c482489f | |||
| 7a0963617e | |||
| e4ec1dc457 | |||
| b035129788 | |||
| 78be8114ac | |||
| 18ad025c5d | |||
| 5825e0c71b | |||
| df64ca4cfb | |||
| fc1f5496a0 | |||
| 5a9dbc5a36 | |||
| eaeeede287 | |||
| e78b3a3977 | |||
| a8ca8217ea | |||
| 77c2e30733 | |||
| 5a3a387b8c | |||
| f68f60832c | |||
| b05417a4d8 | |||
| c2a4e30fae | |||
| 1a0280928b | |||
| dda16c847d | |||
| 47c6c2ce9a | |||
| 3758c454c9 | |||
| 4b6424e0e1 | |||
| d71887d846 | |||
| d61945a575 | |||
| 45e6ae6708 | |||
| ebbf30a88c | |||
| e5769766af | |||
| 64b9d2e5e3 | |||
| 3213ffe760 | |||
| a851689bca | |||
| 98f2bd66b6 | |||
| 1c12a98b68 | |||
| a3859385c4 | |||
| c7394faf51 | |||
| 3907ae656c | |||
| 5fc31be8aa | |||
| 7976fb4d09 | |||
| 01635ecd8a | |||
| f6657113b6 | |||
| 480f1a91a6 | |||
| 4865b62ea9 | |||
| 9a440899be | |||
| 3ee6bdf207 | |||
| 1f43ec8709 | |||
| d030582fbb | |||
| 60a8d9b2fd | |||
| a5de5d8c0e | |||
| b506e7dbbc | |||
| db8f1a9b70 | |||
| 032f52d434 | |||
| 1003e8de91 | |||
| c6ef402b60 | |||
| 5805653431 | |||
| 186da73135 | |||
| 528481e774 | |||
| 886ab52556 | |||
| 8196f31d82 | |||
| de3b844829 | |||
| fa4e19eba7 | |||
| 1488ae40ee | |||
| aa004ef0c6 | |||
| 0c946fae36 | |||
| f297739836 | |||
| b33e58f40b | |||
| 30d9743ae7 | |||
| c974306636 | |||
| 602176815a | |||
| 7652144184 | |||
| 0fd94d291b | |||
| 3c9f09f246 | |||
| d60fbd2c09 | |||
| 9d869ebb6d | |||
| 971e508e3d | |||
| 7020caf682 | |||
| 7cd7ad1281 | |||
| 586707dd28 | |||
| 4bb46fa607 | |||
| 7d5beb6c80 | |||
| ecc0263062 | |||
| 39c5dc6ea4 | |||
| e6d6ab6da7 | |||
| d7c3b5a990 | |||
| 3409cd7c29 | |||
| 91176349f7 | |||
| 6634025346 | |||
| a771061495 | |||
| 2629172ff4 | |||
| 36b746da7a | |||
| d3aa2e87c9 | |||
| c6090ef9b3 | |||
| 6354a11645 | |||
| 11ec8e04c2 | |||
| 8a9998bc65 | |||
| 065bda604e | |||
| 471aeab439 | |||
| f2c757b1bb | |||
| f6e72ec06f | |||
| 9dd82036ba | |||
| ff2fa70776 | |||
| e4b1f56f6d | |||
| 0d7a789ed8 | |||
| d73e77c5ed | |||
| dddbf64e93 | |||
| 1d5891fde7 | |||
| c5de64de51 | |||
| a43b2a2ae8 | |||
| 7ab92dfa0b | |||
| ff81286874 | |||
| 51ad31f5a3 | |||
| 6336db0069 | |||
| 7d7122ee4c | |||
| 7d852f9e51 | |||
| 605097de76 | |||
| 07638dac27 | |||
| 6f39648077 | |||
| 90c19f8454 | |||
| 929aa3a49b | |||
| 83e97b7205 | |||
| 5d583741b9 | |||
| d3d2c3608b | |||
| a0edd66b92 | |||
| c8c0c9a621 | |||
| 00c010e04d | |||
| 1d2c9780da | |||
| adec3853e8 | |||
| d3251c5ca1 | |||
| 68f8d8798a | |||
| 4c793be5f7 | |||
| 812eb5eaef | |||
| 6c2be8f886 | |||
| 301d4fecf8 | |||
| 604dfa8cf4 | |||
| 8bb4ab91b8 | |||
| 0cdd9a0cde | |||
| 4768ea23e4 | |||
| 659cbe69c3 | |||
| e22f4dd001 | |||
| 394b2003b3 | |||
| d72ac7827b | |||
| 610ec7d8ad | |||
| 8f41ae0c1b | |||
| f8113d4857 | |||
| 72169d06ad | |||
| 2b78871c01 | |||
| 1ce254cc9a | |||
| 3b07c086a8 | |||
| ff7b101b71 | |||
| 92405d819b | |||
| c367989ebd | |||
| 7cae099fb4 | |||
| 7dcccf9ea5 | |||
| 535e974cc3 | |||
| 629aff1e50 | |||
| 628b6830db | |||
| 1b2ab4e3f0 | |||
| f97752c368 | |||
| d2d5db9bf6 | |||
| a8554d9e56 | |||
| 11a38af901 | |||
| 27a4976b9d | |||
| eb54f5a0cb | |||
| a4a6dce6de | |||
| 4184e25c68 | |||
| d98b0766c2 | |||
| b8990dd0a4 | |||
| 2198201e0b | |||
| 53e58848f3 | |||
| 9c367d1702 | |||
| db18a81035 | |||
| d1d6b00f92 | |||
| 32fc147a7c | |||
| d98054234c | |||
| d6460026f2 | |||
| 88ba6514e8 | |||
| 894a688bd8 | |||
| c69ead4893 | |||
| e68fdb2db7 | |||
| ae9372c3d3 | |||
| 0365c6d43b | |||
| 18b6969221 | |||
| a1935acb3d | |||
| 9548c5e657 | |||
| 762299124f | |||
| f682bf5688 | |||
| f7ed3a8727 | |||
| c124506e41 | |||
| 273cdc6ea8 | |||
| 0ef6ea6bd4 | |||
| 607d9a06ec | |||
| 1b472ca5f2 | |||
| 18568d6ba7 | |||
| bfb59dd387 | |||
| 38cf88d5d2 | |||
| 7ca6f9d7a1 | |||
| 5874508263 | |||
| 954de793dd | |||
| df74d5efbe | |||
| f7b9a7bfb5 | |||
| 63eaa88d3d | |||
| f518521ea1 | |||
| 5e1ee22bcd | |||
| ca09ff2ef0 | |||
| 8643aff800 | |||
| 2e88993654 | |||
| b77849d279 | |||
| c7e288466f | |||
| bb48d4aac1 | |||
| 2b99cc1e58 | |||
| ca286f8d19 | |||
| 73a3cc2cc5 | |||
| 169709ed04 | |||
| 2e746242ce | |||
| 951b8e2b15 | |||
| ede3edcf1e | |||
| 184c9f87b2 | |||
| 0793a4602d | |||
| bb285c47dc | |||
| 4cb6fc05d6 | |||
| a302e5db64 | |||
| ff21749da4 | |||
| 23b5da7670 | |||
| c31e479f47 | |||
| 260eb31a69 | |||
| 1fb6dac6fb | |||
| 34d947c51f | |||
| 23f7a6d5a6 | |||
| b15926c20a | |||
| 0a7ef80ca7 | |||
| be08406cc1 | |||
| cc9777b1e8 | |||
| 539b3a243b | |||
| 41e58a3d46 | |||
| 8c302ed85c | |||
| dc4dc46b62 | |||
| a07fa5a2c2 | |||
| ad9dbce003 | |||
| d0526d0ae5 | |||
| 75e9c3265d | |||
| b37705ab6e | |||
| d9d5f86a6e | |||
| 1f3ad95c00 | |||
| 9e360f7efa | |||
| 64fd6a1f52 | |||
| ba04df4ce3 | |||
| cd27a026fd | |||
| baedf71106 | |||
| 4f6c95b119 | |||
| b1761ac393 | |||
| fcdf3e583f | |||
| 2001119dff | |||
| 60a9d96ac8 | |||
| 6bd177d250 | |||
| 1ece84e31d | |||
| 40ea9457a8 | |||
| e95d91a91e | |||
| c8fb92175f | |||
| a6fb4cbfbf | |||
| 30bb6d05c5 | |||
| 9422f804fb | |||
| 415a7746be | |||
| ee903208dc | |||
| f89e834fea | |||
| e8b4335741 | |||
| 83010f0542 | |||
| 04e5f5036c | |||
| 5d86d38a14 | |||
| a82db1f622 | |||
| fb618d536b | |||
| 23f96779fa | |||
| 7b67854654 | |||
| 2e7f941465 | |||
| 1c1706fde3 | |||
| ca77a895e0 | |||
| 0f447f964e | |||
| 2c31fc6b25 | |||
| 0ba79dc105 | |||
| 52c686b656 | |||
| 64d98f1295 | |||
| ceb2c4075c | |||
| 166e7d52ec | |||
| 644c2652ea | |||
| 63b201fd95 | |||
| d70616056c | |||
| a65e376886 | |||
| a985c70f0c | |||
| 0d09e02e7e | |||
| 23e3551f27 | |||
| 885bca0865 | |||
| 0f874dad51 | |||
| 107873cf6e | |||
| 4a8f5af7ba | |||
| 83084aeb7b | |||
| 51640ccc28 | |||
| aefbc134ea | |||
| 29e1d70334 | |||
| 9118e529e6 | |||
| 8ee0a1611d | |||
| 2af4388f40 | |||
| 93a2d18ea6 | |||
| fc49859ea4 | |||
| c0ac9cb380 | |||
| d5cc6c3c8e | |||
| 9b22b5000f | |||
| 3b69a4cc78 | |||
| adf54efcc5 | |||
| f6962eb58e | |||
| 11601d6532 | |||
| be2131d62c | |||
| 3ffbf46ac2 | |||
| 3943107eec | |||
| 94e3f75341 | |||
| 8bc8b950e7 | |||
| 05a95ac666 | |||
| f016c803e4 | |||
| bac0dd37fa | |||
| 75a37cf737 | |||
| bb7e9c4610 | |||
| ee2f18349f | |||
| 8829a3cbe9 | |||
| b210e39c7e | |||
| 4d4500f061 | |||
| 79860a0c04 | |||
| d53fcdc616 | |||
| 5e6a094ac6 | |||
| 757bf4e916 | |||
| 7bb57b3ab9 | |||
| cb22b5804d | |||
| bfbced3859 | |||
| c090ee9b83 | |||
| b6caf069d0 | |||
| 5b4449eea0 | |||
| 7dc17a3653 | |||
| 598bf799de | |||
| 4774a37d48 | |||
| d9a1e6f4b1 | |||
| 72dae8e9ad | |||
| b2d7fb9443 | |||
| bf945e36bd | |||
| 2bcfe93dd2 | |||
| 195ef743c6 | |||
| 8478eb9aa0 | |||
| 47f57d20cd | |||
| 8f8eb06d6b | |||
| 7d6803f325 | |||
| f9b7a8b92b | |||
| 7ee0c047e5 | |||
| bfbfe17644 | |||
| 046940f949 | |||
| 2950ddcf4f | |||
| 3d441b4ad3 | |||
| caa5e8983b | |||
| 59b7944d8e | |||
| 648eb8fdd1 | |||
| f160516772 | |||
| 4beb7780f8 | |||
| d44b6d40e9 | |||
| 8fd9f5a8cb | |||
| 414af2f55e | |||
| 8624be6bcf | |||
| 4aa26b613b | |||
| 57cb062d48 | |||
| b4b6404b65 | |||
| 989dd2be50 | |||
| 50b8baddec | |||
| 2e00c3db0b | |||
| 232260787e | |||
| 54054c4aee | |||
| 1a7843a6b5 | |||
| ed4ba4d0d3 | |||
| 849d6118d0 | |||
| 364138d408 | |||
| 32c8da06ca | |||
| 2df4c5825f | |||
| 527cbc3ae0 | |||
| 4fee8744d6 | |||
| 8f8862d23d | |||
| 836f36fd8e | |||
| a1326cb5ed | |||
| 4bfda8851c | |||
| f02f15cbfb | |||
| 30182684d5 | |||
| 7df80af30b | |||
| 6b2e867107 | |||
| d333090b09 | |||
| 8ae7763ac5 | |||
| 51ac86be79 | |||
| 552078c8a2 | |||
| 4b4ede733f | |||
| d07e8bc747 | |||
| 8850d78e5a | |||
| 4fbf4e7d42 | |||
| d6e1a670b9 | |||
| 1a32c8827e | |||
| 784b5156df | |||
| 6e3336afb1 | |||
| d0ddee3623 | |||
| 9cf55033d4 | |||
| 7371efde17 | |||
| 156269a53f | |||
| ed7e5fb482 | |||
| 2e973a4591 | |||
| f1bd82d301 | |||
| f51bfa314d | |||
| 7b3410c7b1 | |||
| 6b0e7d51b1 | |||
| 4e5659efad | |||
| 66f10adde8 | |||
| 459c4d7fcc | |||
| 03d9efb790 | |||
| 33bd6099ee | |||
| 850a1d326b | |||
| f0bb19d48d | |||
| a56eac0131 | |||
| d3201809ab | |||
| 3628a0e241 | |||
| 07badd3df5 | |||
| f63091ce05 | |||
| 617b2978c0 | |||
| 364e96ad1e | |||
| 9170e5ca65 | |||
| cbe71f221c | |||
| c039c01407 | |||
| 629ba41f5f | |||
| 198fa67cc1 | |||
| e7830e3d55 | |||
| 90bfb25f41 | |||
| 037cb00caa | |||
| f002124c38 | |||
| ac42f9f599 | |||
| 88d4640d3f | |||
| d2da01041c | |||
| 75c17b820f | |||
| 2dc4bbf8cd | |||
| c9a5abc3be | |||
| 7ea468a9a6 | |||
| c6223520e0 | |||
| 176cbf9861 | |||
| 00315a6f2d | |||
| 2145b2f8e2 | |||
| 31155e7bc9 | |||
| 2d07208d0f | |||
| 35ad7e16c6 | |||
| 27c52fe6d5 | |||
| e153f63a23 | |||
| 2cbbc360c0 | |||
| 8a4a42777f | |||
| 352d6b5ef9 | |||
| cc49b0efdc | |||
| e71ee988bf | |||
| 937a5b2c2d | |||
| 92221e19c3 | |||
| e5c920864c | |||
| 6f63682bdf | |||
| 7623eddcd7 | |||
| d1dee1e908 | |||
| 8b302f8d21 | |||
| dfeebd6b6b | |||
| df53ce9f6e | |||
| 9bb2c00b6d | |||
| 641253c4c6 | |||
| 6ce49b7130 | |||
| 804ad0cece | |||
| 6c60d14c05 | |||
| def2d2bcc9 | |||
| 9bca705dc3 | |||
| 2dcc271dff | |||
| 33415fa1af | |||
| 10315e0e29 | |||
| f321cc81c8 | |||
| 68b685f580 | |||
| c87c79b937 | |||
| de3dfcdc43 | |||
| 657ddc0fa1 | |||
| 1da01489f1 | |||
| 64a27614ff | |||
| 6c5acfc8bb | |||
| 884ee5b587 | |||
| c2320a3c1e | |||
| ab23030051 | |||
| 699c692f6c | |||
| 0c85e26950 | |||
| 2cd7e737cd | |||
| a1adbe2b34 | |||
| a144c2b7ea | |||
| 201c056ffa | |||
| 2e95168610 | |||
| b18c05cbb9 | |||
| 102a4c6110 | |||
| b6c0ef3d19 | |||
| ea3065dbc2 | |||
| 534c3ad329 | |||
| 90a7d807a1 | |||
| 4baafb5e2f | |||
| f911765cdb | |||
| d0a36c79d5 | |||
| ffea5320a0 | |||
| 0b54e41a40 | |||
| 26c67f770a | |||
| f6623db0e6 | |||
| d7844ee8e8 | |||
| 1c8970bbf2 | |||
| eb70849a30 | |||
| 77ce3c9067 | |||
| 56cd226a27 | |||
| a1acdc0977 | |||
| 1a624c957b | |||
| 1c9eeb2aca | |||
| 45f06eeea7 | |||
| 66a53b486a | |||
| fc45f5b48f | |||
| c7105a22e6 | |||
| e1fc7cad44 | |||
| afeeaeb984 | |||
| 2bc60b87f2 | |||
| 4ad9ecb7db | |||
| 3ec7b82b85 | |||
| 48666def6b | |||
| 5732921fb6 | |||
| b86c11e1dc | |||
| 1bae4b219a | |||
| 70ff73f805 | |||
| a9636c5038 | |||
| a406b9f7ef | |||
| f291345111 | |||
| c947ccb8be | |||
| 28c6b0d4bb | |||
| 19317a9cc2 | |||
| d67da6425e | |||
| 901f41358f | |||
| 061922aea2 | |||
| 5f7b6a5498 | |||
| 2ef9d5eed9 | |||
| 9fba57d5db | |||
| e9074e3b3f | |||
| f053ba714f | |||
| b6598f09a3 | |||
| b9d7b95304 | |||
| 3db540f786 | |||
| 071b99c6c6 | |||
| 3a3d96be0a | |||
| a03fbab4d5 | |||
| cc3b119288 | |||
| 1a750d1b85 | |||
| 5b3ae9b9fd | |||
| 81471d80cd | |||
| eb14db4deb | |||
| 50d989363a | |||
| e52a99bd71 | |||
| a7a7c86657 | |||
| 59b8347082 | |||
| 86883770b8 | |||
| d19c7d27a8 | |||
| eb35aad6e3 | |||
| 5f952ecd00 | |||
| 74cd28d761 | |||
| 6e8049c43b | |||
| bbc61483ad | |||
| db5315249c | |||
| 4d34404e47 | |||
| fa261b3281 | |||
| 73feadcd66 | |||
| da84165e13 | |||
| cc550c413b | |||
| 5b8b68457f | |||
| 7850f8c718 | |||
| 3502b560f0 | |||
| 53aa5e5fe0 | |||
| 674526d2df | |||
| 384c9c9872 | |||
| 1170448cd0 | |||
| a7ec9c097a | |||
| 9b3b29a91c | |||
| 16c4b212fd | |||
| 50ba0815f7 | |||
| 8d3347c02b | |||
| fbd57a2bd7 | |||
| 75c98e5b00 | |||
| c725eeb5db | |||
| 75f56462b5 | |||
| f6ca12d3b8 | |||
| f6b7201bc4 | |||
| ab618be49f | |||
| 5943e7e62e | |||
| fde654aee7 | |||
| 4880e1f9eb | |||
| 8083a635a8 | |||
| fab76bbcde | |||
| 7f78df595f | |||
| 03ff34f89f | |||
| 8820a1dcc3 | |||
| 514975d123 | |||
| c87911f00e | |||
| 1e77562f0f | |||
| b1843ce781 | |||
| 02fb09ff7e | |||
| bdb193f500 | |||
| e9a3630595 | |||
| fb3e4016ec | |||
| 15a1aa5355 | |||
| f1d6e95e51 | |||
| b9c99b35a5 | |||
| df0a503b89 | |||
| 346071185f | |||
| f3f90e0ad5 | |||
| 8aa2c1eea7 | |||
| 57c32e55c2 | |||
| de080a668f | |||
| 00fc71dcbe | |||
| 808cb6ec14 | |||
| 8899776106 | |||
| ae674b00c2 | |||
| 73b6d23d4f | |||
| 6d1cabe534 | |||
| ab34fda42c | |||
| fab4133df6 | |||
| 301e368a2c | |||
| 0a22714fb8 | |||
| ef2cec7435 | |||
| b4f486e9aa | |||
| 297303063e | |||
| df95bdb48e | |||
| 95ac021623 | |||
| 416efa4f14 | |||
| 2003bfe4fe | |||
| fc55a48c11 | |||
| 37a6be1e2b | |||
| e551bf531c | |||
| e173ea7f80 | |||
| f8dc421f03 | |||
| e2afb34e0d | |||
| f7181aae8a | |||
| 2a0fdd214c | |||
| 45209be0ff | |||
| fcb3640bee | |||
| d503a4b50b | |||
| 8bae2984e1 | |||
| 78499cc55d | |||
| b6aa5c57c0 | |||
| d71e34f073 | |||
| a38d06d7e7 | |||
| 72b5cc8a44 | |||
| c97e1079e8 | |||
| 65caa7906d | |||
| d89a8520a9 | |||
| d68356c3a7 | |||
| cb0e8b6bf2 | |||
| b20b99669d | |||
| d41a277b71 | |||
| 33e6a0fdae | |||
| d911d8579d | |||
| 05bdc962a3 | |||
| 0e03a01f61 | |||
| ff806dc6e4 | |||
| 5fcfbac4a3 | |||
| 00b18f67cf | |||
| 088354a96b | |||
| cfd857233c | |||
| 2816d7f522 | |||
| 3da718a6d1 | |||
| 558aff72a0 | |||
| bcc399b842 | |||
| 32e47d03d4 | |||
| a669c194cf | |||
| 91f4687eac | |||
| 31f6baaf67 | |||
| a83c4b2896 | |||
| c685425667 | |||
| 553334d50e | |||
| 0b7b0a29a9 | |||
| ae7f834a0f | |||
| fe0a98a44f | |||
| 35e748089b | |||
| ff2cda7d18 | |||
| 0d473fa9ac | |||
| d8eb765906 | |||
| fab7b590f7 | |||
| c9f52d2f8e | |||
| 821993d289 | |||
| 2d32bc609a | |||
| 296cec02e8 | |||
| b55ac88c9d | |||
| c6d3598c52 | |||
| c4d2b30017 | |||
| ee1e401719 | |||
| 3c2ef518e8 | |||
| f3e327e088 | |||
| be1d4e06de | |||
| 32f5a77d07 | |||
| 9121a6b864 | |||
| 9946117de1 | |||
| ee85055d45 | |||
| cce0867f63 | |||
| 021321eb65 | |||
| 6bd1b84b2b | |||
| f5281a0895 | |||
| 08fdf6014d | |||
| 94f06d9e18 | |||
| 8405ee4926 | |||
| 154c4295df | |||
| 93519c1c63 | |||
| 1250a20e35 | |||
| 9ec54228f8 | |||
| 3f94184ace | |||
| 88c06f5450 | |||
| e50045bbed | |||
| 41417a77b9 | |||
| a5774bd02a | |||
| c38f48ee62 | |||
| 30c850e37d | |||
| b6fdbd979e | |||
| 7a8bcbee33 | |||
| 42d7c7d32c | |||
| c71a5a4d65 | |||
| e69452883f | |||
| 8624888bfc | |||
| fad5c7c921 | |||
| 0dad93bf00 | |||
| c51aa910cb | |||
| 6d486aeb4d | |||
| 7041a4a4a9 | |||
| 381570cd9e | |||
| c9f93b2316 | |||
| 3706ecc5f2 | |||
| 51ad51036e | |||
| 3edbcb9ff8 | |||
| 3e3c1699da | |||
| 7666463751 | |||
| c532b90c92 | |||
| 7677733850 | |||
| 972d701801 | |||
| cdee5532b6 | |||
| 38019288de | |||
| 3e2ca328d2 | |||
| 93b44b43a5 | |||
| 4ebcf8133c | |||
| 13f8b183cb | |||
| 8e5154e65e | |||
| 6d524b632c | |||
| 4ad3d65628 | |||
| 4282014bfa | |||
| daee666735 | |||
| 5a6ae57833 | |||
| da8e5dced1 | |||
| fb38c68c7d | |||
| 2dc3c9b027 | |||
| b057312ebf | |||
| d1217e61c4 | |||
| b521b68fd8 | |||
| c9302cde7c | |||
| 823e3c76eb | |||
| 30d6289942 | |||
| a43a3d1ecd | |||
| 9e0c5e9244 | |||
| a8f1df8a50 | |||
| fba84ecd3c | |||
| 8cc4edf60f | |||
| e6eb455d71 | |||
| b84782e07f | |||
| 2e3e0bef12 | |||
| 51ff2f05bf | |||
| 42110e7f63 | |||
| f0733cb148 | |||
| 7383f44f8f | |||
| 311a80955d | |||
| 08561b11c3 | |||
| 47192cc834 | |||
| 860a0bfc8e | |||
| 5677768e99 | |||
| 4c58ca28e5 | |||
| 588d6ccaaa | |||
| 21f583800a | |||
| 4ea08a087c | |||
| e5885db187 | |||
| 1fca38625f | |||
| cf2ad43ed7 | |||
| fb3023bb79 | |||
| 52f18fea85 | |||
| d5ecb9b8ea | |||
| 67d33001d5 | |||
| 4f571fa2fc | |||
| c5bd902dc6 | |||
| 68282c7a1e | |||
| d40dcae212 | |||
| 12151c40ff | |||
| 9c8b15fa1a | |||
| 3d49cc9d13 | |||
| 955c0d19a6 | |||
| 3cf7a9e925 | |||
| 8cbf719772 | |||
| 2f614330c9 | |||
| 5a40519114 | |||
| 96271e8bd8 | |||
| 9b75a415d4 | |||
| 5f71abb5fa | |||
| affb066b7b | |||
| 17add48254 | |||
| f5b6fdcb5b | |||
| 68bdbe4c4f | |||
| 363ddc2a9b | |||
| 20d44378d9 | |||
| 4fe321275a | |||
| 60b1192703 | |||
| b25233a748 | |||
| d9b54c923c | |||
| 131ee8270b | |||
| e71bace6a8 | |||
| 2c4a0669ed | |||
| ee451b6b29 | |||
| 7b858fffb2 | |||
| 6ce0deeb63 | |||
| 96b2eaeae4 | |||
| 8fe8175a87 | |||
| ee2bedfb64 | |||
| aa8da74ed8 | |||
| f2c03a508f | |||
| aa172488b0 | |||
| ae09adf854 | |||
| 5b5dd73684 | |||
| 3849a87adc | |||
| 708dc6aca2 | |||
| 2fe2c349fd | |||
| d396d32a8f | |||
| 1fd02755f8 | |||
| 79d92b511b | |||
| ff7d93e66c | |||
| 68a8c7a235 | |||
| 5e744ff7d1 | |||
| 921a185ffa | |||
| 855751f026 | |||
| 255c2efe98 | |||
| 892b282054 | |||
| 26efc6b4e7 | |||
| a0618c5827 | |||
| d4bbb6e2c7 | |||
| 66b7692227 | |||
| 2429f507ad | |||
| 03a66d2806 | |||
| 9d8551cb48 | |||
| 2ca0b52c6a | |||
| 9cc754488b | |||
| f81ceb53cf | |||
| d1d0b5724d | |||
| 40560b71c2 | |||
| 378a25bbaa | |||
| 1dfabe2591 | |||
| 0e1689c2d9 | |||
| bd071cc472 | |||
| dde847cb5a | |||
| 3c17718f70 | |||
| 0445119e77 | |||
| e82cb5c149 | |||
| 984548f315 | |||
| a0be4f58e6 | |||
| 147602e107 | |||
| ac81169290 | |||
| 1d78e05370 | |||
| 4b15b02ac8 | |||
| 57d18a0644 | |||
| 2f73af7e6a | |||
| e712ef344d | |||
| f91e9a3119 | |||
| 9cf36f1d91 | |||
| ab9a4856ab | |||
| d52618277e | |||
| 743bd2c48f | |||
| 11894de455 | |||
| 0c8122afc4 | |||
| f893503d0c | |||
| 504782f156 | |||
| 5d1f32bfc0 | |||
| 5bc315be92 | |||
| e8f21c79b1 | |||
| ba24f9b491 | |||
| 937fa21cce | |||
| 16cbab2de7 | |||
| a85f81d8ca | |||
| 1617ede010 | |||
| d9f1d501aa | |||
| 8ee60db0df | |||
| d2e02c8ab3 | |||
| 2d4e4d2445 | |||
| 9dc69f3aa7 | |||
| 476ab506d0 | |||
| a6fa6201f7 | |||
| 26f7db0504 | |||
| 77a0da2a17 | |||
| 785d2e601c | |||
| 3687e4ed91 | |||
| 31cf1127a6 | |||
| 97385efbca | |||
| 6a87b68c3b | |||
| be06bd6369 | |||
| a5b4ac863b | |||
| e535f911d1 | |||
| 18670bcbd6 | |||
| 27511d362e | |||
| c634bffa10 | |||
| dffa90bd5d | |||
| 6a47d33974 | |||
| e87524ba11 | |||
| b1154ae377 | |||
| cbc24c31a2 | |||
| 0a8a6e5825 | |||
| e088a10aa8 | |||
| 007d984baf | |||
| 7d979e5a04 | |||
| 4134c709a8 | |||
| ff5e4991ab | |||
| 0b4b45b7c8 | |||
| 145ac1a0f4 | |||
| 74de7436b7 | |||
| 60fa05a913 | |||
| 303de61417 | |||
| a9a4c6049f | |||
| 82b201a14e | |||
| c9bd7adf8a | |||
| 0655d77210 | |||
| 515ec28fb3 | |||
| c28c2dd077 | |||
| b04383bb64 | |||
| f4b93ef243 | |||
| 05cf00bef6 | |||
| e81346c339 | |||
| ac911cefd6 | |||
| c4cea20849 | |||
| e30992b905 | |||
| 5beea8640e | |||
| d3b176e5eb | |||
| 0d0691a012 | |||
| d4eb56e360 | |||
| 5cfc122b79 | |||
| fa0f484922 | |||
| ceaa930aad | |||
| bbd2b67041 | |||
| 6c82e6f889 | |||
| 531e07767f | |||
| da39c903f3 | |||
| f458aa9932 | |||
| 9e383959c8 | |||
| 3654e49f87 | |||
| 13f5767921 | |||
| 6d1e9f73a6 | |||
| d9ddf67afb | |||
| 47e6352350 | |||
| ae564d1b61 | |||
| d9cee04769 | |||
| 50d71d5ea1 | |||
| 25c650f4cd | |||
| f0502c123e | |||
| 693960a4ab | |||
| 5df0cf39a0 | |||
| 578220a1ab | |||
| ae5ea3857e | |||
| 93d0ffd459 | |||
| 1b85928810 | |||
| f118c50d1d | |||
| ac5ec72acf | |||
| 7fe2634d32 | |||
| 1279b9848f | |||
| ea91f4302c | |||
| 88bddb9531 | |||
| 4e308a6e31 | |||
| 4bd7fc5304 | |||
| 0122fe4382 | |||
| 1730f25a5a | |||
| 3f8314bcf3 | |||
| 5879d14803 | |||
| 4c1a821922 | |||
| e1456533f2 | |||
| 7522a3a2ab | |||
| 144d01a0ef | |||
| f6cb6c8b21 | |||
| 0f5264af99 | |||
| e57ff19e16 | |||
| b2bdbdd8c3 | |||
| a8400ec963 | |||
| d028b52d77 | |||
| 65990255e8 | |||
| 3a71b03a9a | |||
| 99274c2d7a | |||
| e40bbf2525 | |||
| 38c6378315 | |||
| c050ca1037 | |||
| 9813dda778 | |||
| 6b7aeb90c7 | |||
| 3cb29e1344 | |||
| 4d4961a490 | |||
| ccd7db06f8 | |||
| 77234706b0 | |||
| 9f399b34fb | |||
| dc77a798b5 | |||
| 207093fe99 | |||
| 42c4a68108 | |||
| a7cc58fb50 | |||
| 6bab10d2ac | |||
| c4b77c2a07 | |||
| 66d0627035 | |||
| 3f4417c9f2 | |||
| 5526bed4c3 | |||
| 078bf8646a | |||
| 6adbcdd8e1 | |||
| b4d633a34d | |||
| e1e4380fc7 | |||
| 1ed7b21ab0 | |||
| 158a4c5e75 | |||
| f72d48aab5 | |||
| be26a77ecb | |||
| 7c275a99a2 | |||
| f77d2f449d | |||
| 18ba805a15 | |||
| a5adf0021f | |||
| 7d944255d0 | |||
| b984a77862 | |||
| d69aa20802 | |||
| 7e16cb797f | |||
| b3c7971ea9 | |||
| a778b98fdb | |||
| 4efb80efe4 | |||
| cfaacf8650 | |||
| 60da4cb87b | |||
| db6207db6c | |||
| 9b4568c881 | |||
| cd132d4fe9 | |||
| f01900bdb1 | |||
| 0fddd243c2 | |||
| 1066e5e0a7 | |||
| 7e0b1b9cbd | |||
| 95e924a5bc | |||
| f9cfd17303 | |||
| 9f37f73e52 | |||
| 9acd2043d7 | |||
| ab6159f173 | |||
| f9bff64f0d | |||
| 978f362073 | |||
| 7a185e7f7c | |||
| 044cd6e97b | |||
| b939370f2b | |||
| 4af0c1c98c | |||
| 181531ada8 | |||
| e92d908063 | |||
| 686f4a023d | |||
| c0c6c23fca | |||
| 396fd5520f | |||
| efc3a692cb | |||
| 2902d96690 | |||
| 70f35095ff | |||
| 87c67abac9 | |||
| 7df9640807 | |||
| 25edc91976 | |||
| 2174fda88d | |||
| 2fc5c6c110 | |||
| 6a2307308c | |||
| 1a05fae826 | |||
| cce27d73fd | |||
| 87515f3839 | |||
| 24f3918769 | |||
| f7af38c863 | |||
| 6c2a4711da | |||
| 41fdd77bfa | |||
| 9185a51234 | |||
| c5ae86d10b | |||
| 74477d0051 | |||
| cee0ff2074 | |||
| 85bba9d5f8 | |||
| 8e696cbf02 | |||
| c7d1f5efc0 | |||
| 68bbb4d7a1 | |||
| b1dd20fef7 | |||
| a701624d7b | |||
| f912be7875 | |||
| 04bdb12e79 | |||
| d69f6c02b6 | |||
| 95c3a57a4d | |||
| 0b6d321d83 | |||
| e0fd3fd90e | |||
| 7686e35858 | |||
| 8eeb8804d4 | |||
| cb9a7cf5be | |||
| 54cec30a60 | |||
| 9f0ad9be3c | |||
| a6271d0936 | |||
| cf6acd5dd6 | |||
| f8468e66e6 | |||
| d0cf5f9d0c | |||
| 2c123fdbfb | |||
| 49b5bbd585 | |||
| bf3063ec00 | |||
| 1e2ac1fe24 | |||
| 9d7145746f | |||
| 6e7fee5bc8 | |||
| 9638ae3e77 | |||
| 69cee56b7c | |||
| 2257942676 | |||
| a5ca7c540f | |||
| c9b0a7c3de | |||
| 358d19c883 | |||
| e624d56516 | |||
| 78a6532615 | |||
| 44bb4ac74d | |||
| f782d784af | |||
| caf9034839 | |||
| 893fd50b85 | |||
| 7a3e53a9f8 | |||
| 07ee62eb91 | |||
| b41878e960 | |||
| d9f1cb5525 | |||
| 8110951987 | |||
| 6b63b5aae7 | |||
| e814736e68 | |||
| 802e3a0ea1 | |||
| 4e8a962f60 | |||
| e20d4c93b7 | |||
| 1be76c8aaa | |||
| a4566797fe | |||
| 4ee3458ff9 | |||
| f86de533f8 | |||
| 693831dca3 | |||
| 7500919b5d | |||
| e37b6fa8a2 | |||
| 9de9645229 | |||
| 373d664251 | |||
| 6ab912a049 | |||
| 9b9c900340 | |||
| a1ac820050 | |||
| e812a886dc | |||
| b759e22875 | |||
| 93e0babe5a | |||
| 7d021fb7a4 | |||
| b2cb8ffd8f | |||
| 25a5651e50 | |||
| b301eb6520 | |||
| 9f90d37401 | |||
| ba7741fef5 | |||
| d1a40d129f | |||
| 791076df2d | |||
| 608952a4dd | |||
| e64047c511 | |||
| fc3c6599c7 | |||
| 2336f299f7 | |||
| 4a71ab9631 | |||
| ac3c4cac89 | |||
| 2be1baab32 | |||
| 3e42fdb883 | |||
| ed37d11002 | |||
| 4cf896f564 | |||
| 7e151799b0 | |||
| 597b2bb0a8 | |||
| ddc0f7e652 | |||
| 4845d191f4 | |||
| da84cc5925 | |||
| c8ba96cde8 | |||
| 66e067d1ce | |||
| 9d39760f6f | |||
| 8aa4934d92 | |||
| f848340124 | |||
| b699f55d9c | |||
| 745709c56a | |||
| 0c4c8ad9bc | |||
| 3ce010de77 | |||
| dd600dd20f | |||
| 360b9956c0 | |||
| 1888048d4d | |||
| 4ab6d648c9 | |||
| c29048ecfb | |||
| 0294c4e02c | |||
| 3cfcd847cf | |||
| 694b21a0e1 | |||
| 73d43649a5 | |||
| 55036653df | |||
| 66ecb92cc2 | |||
| 23c7bc3f56 | |||
| 74fee24004 | |||
| 618ecccb7b | |||
| f818fc659a | |||
| 4afada48a6 | |||
| 59451cb90c | |||
| 53bf746227 | |||
| cd6f995471 | |||
| 839a00c2a8 | |||
| 9208781b8f | |||
| 25af42f4cb | |||
| d386a884aa | |||
| cb92be2b08 | |||
| 70b7f1424f | |||
| 56858540b8 | |||
| 0331a21280 | |||
| 9f53d724d1 | |||
| c114f09f9a | |||
| 1a2183ef71 | |||
| 0ab0213dea | |||
| 421f861e46 | |||
| 6e5f2f3f8d | |||
| 05633cd657 | |||
| 41ae350f33 | |||
| 8a26f30506 | |||
| 4ae7643874 | |||
| b09068e1f4 | |||
| 87dbaa39d8 | |||
| d193e8a3eb | |||
| f9e766138c | |||
| 36899d362e | |||
| fd789178c1 | |||
| a0757851c8 | |||
| 039727cb19 | |||
| b5133f1c41 | |||
| ab218b842a | |||
| 37aa17fcf3 | |||
| 6542fc7db3 | |||
| c8c690afc2 | |||
| 5d569dea30 | |||
| 38031a02bc | |||
| 25460661ab | |||
| 3684be1936 | |||
| 0ada921ad8 | |||
| 8fb285596a | |||
| ba4130d395 | |||
| f818446e7e | |||
| 82ac895bbb | |||
| fd8774718e | |||
| 90d4d5afda | |||
| 92623b98e2 | |||
| b86818ead3 | |||
| 9e45435024 | |||
| 981b6cd65f | |||
| 0c77fb81ce | |||
| e53a9cd66c | |||
| 2805109cef | |||
| 6594445fa3 | |||
| bac6c62073 | |||
| 6180d73f75 | |||
| 599c391407 | |||
| 1f18c5ab82 | |||
| 2bb4e645b2 | |||
| 5326e21fef | |||
| 891b49ff6f | |||
| 0f9c84c1ce | |||
| 2ccf25f7eb | |||
| 082a326e67 | |||
| d33a7244a3 | |||
| bdb352ab22 | |||
| 04fb7cdf9c | |||
| 16de2f2e7e | |||
| 0b6c8fe83e | |||
| d11959d303 | |||
| 2bd5f3bbb3 | |||
| cabc91dd5e | |||
| 88c9f15320 | |||
| b206e90097 | |||
| 73d3e9589c | |||
| 84a07c3fdf | |||
| ea1c306733 | |||
| 30dc13f1a7 | |||
| 9b3b06adf3 | |||
| 436482532d | |||
| d2fee728f2 | |||
| 0ccea3cef8 | |||
| 241406f676 | |||
| a89c061b58 | |||
| 1211c153d9 | |||
| a5bdcf488b | |||
| a5a1ef2e8e | |||
| 05cd11ae12 | |||
| 307f9a2322 | |||
| 3d05dc234a | |||
| 1f87165601 | |||
| a513e1b56a | |||
| ec0c8f509e | |||
| a23bac6ecb | |||
| 569c19abca | |||
| dfeac601e4 | |||
| 53cecb3546 | |||
| cf87852d9c | |||
| 7da3d9ee70 | |||
| 9650bbb5ee | |||
| 45953c6b49 | |||
| b34caa1b5f | |||
| ea8433b187 | |||
| 390f23a30c | |||
| c8ba2b53c9 | |||
| dbbbb52e9e | |||
| 052d6e2254 | |||
| b05c711fb9 | |||
| eb0322759c | |||
| 25a7a95284 | |||
| 8ec1b7bb3e | |||
| 5f094f6a95 | |||
| f0b1935861 | |||
| 2540ba3467 | |||
| 88093728a7 | |||
| af6734d7b0 | |||
| 8a108f37c3 | |||
| d88510b919 | |||
| afe9f7602f | |||
| ff2b79a41f | |||
| 631722303f | |||
| 4b20a407e9 | |||
| b23f445946 | |||
| 09c8268494 | |||
| 0bc3543914 | |||
| 0412eb48a0 | |||
| e7d5add13d | |||
| 25948a608a | |||
| 11f772b5a3 | |||
| 412cf7c6cb | |||
| b2d5580c37 | |||
| 8386aa0e0a | |||
| ae0f2a9de6 | |||
| 4e0a19e013 | |||
| 9a840174d2 | |||
| 83528ba80a | |||
| eb23372fd0 | |||
| 286e9dfda9 | |||
| f0b9c9ad7b | |||
| afd79ee16d | |||
| caa4445eb0 | |||
| f850bd5741 | |||
| 8c5883ffaa | |||
| 8f8940de2a | |||
| bf59871db5 | |||
| 22eb0bf2e4 | |||
| 68838a37e5 | |||
| 22b4bfe07d | |||
| ff2714d991 | |||
| 308ee7f7a9 | |||
| c87924c4ba | |||
| 8f33c2ca9d | |||
| 9351038009 | |||
| 66281ec1f1 | |||
| ae843e6faf | |||
| 5ca0a254ff | |||
| c18458b3db | |||
| 3736a8b4b4 | |||
| 6558f68cd4 | |||
| 4fd5806f70 | |||
| b1c730c04d | |||
| bdec443410 | |||
| d9afb0f8a2 | |||
| 9dfd7e03f7 | |||
| 31b633b8b6 | |||
| 20f4737ffd | |||
| 4d4ab63404 | |||
| 056f7610c1 | |||
| bfb2f06e44 | |||
| a7febaa9b0 | |||
| ff984f62af | |||
| d005524c4c | |||
| a2362668a3 | |||
| 277317e6fd | |||
| b3f0b9b37b |
@@ -29,7 +29,7 @@ jobs:
|
||||
sudo apt-get install --no-install-recommends \
|
||||
git cmake gcc g++ libboost-all-dev python3-all-dev swig libpcre3-dev libxml2-dev \
|
||||
libocct-foundation-dev libocct-modeling-algorithms-dev libocct-modeling-data-dev libocct-ocaf-dev libocct-visualization-dev libocct-data-exchange-dev \
|
||||
libhdf5-dev libcgal-dev
|
||||
libhdf5-dev libcgal-dev nlohmann-json3-dev
|
||||
|
||||
-
|
||||
name: ccache
|
||||
@@ -61,6 +61,8 @@ jobs:
|
||||
-DGMP_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu \
|
||||
-DMPFR_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu \
|
||||
-DHDF5_INCLUDE_DIR=/usr/include/hdf5/serial \
|
||||
-DGLTF_SUPPORT=On \
|
||||
-DJSON_INCLUDE_DIR=/usr/include \
|
||||
../cmake
|
||||
make -j $(nproc)
|
||||
make install
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import pathlib
|
||||
import shutil
|
||||
|
||||
import requests
|
||||
import zipfile
|
||||
import os
|
||||
|
||||
# To test this locally, set these environment variables
|
||||
REPO_OWNER = os.environ.get("REPO_OWNER", "IfcOpenShell/IfcOpenShell")
|
||||
MY_WORKFLOW = os.environ.get("MY_WORKFLOW", "ci-ifcopenshell-conda-daily")
|
||||
WORKFLOW_RUN_ID = os.environ.get("WORKFLOW_RUN_ID", None)
|
||||
TOKEN = os.environ.get("GITHUB_TOKEN", None)
|
||||
# To test this locally create a fine-grained personal access token for this repo with permissions "actions:read"
|
||||
# See https://github.com/settings/tokens?type=beta
|
||||
|
||||
# This is a list of strings that indicate that a job has stopped abruptly.
|
||||
SIGNS_OF_STOPPAGE = [
|
||||
"Error: The operation was canceled.",
|
||||
"fatal error C1060: compiler is out of heap space",
|
||||
]
|
||||
|
||||
|
||||
def start_request_session():
|
||||
s = requests.Session()
|
||||
headers = {
|
||||
"Accept": "application/vnd.github+json",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
}
|
||||
if TOKEN:
|
||||
headers["Authorization"] = f"Bearer {TOKEN}"
|
||||
|
||||
s.headers = headers
|
||||
return s
|
||||
|
||||
|
||||
def get_ci_run(repo_name, run_id):
|
||||
url = f"https://api.github.com/repos/{repo_name}/actions/runs/{run_id}"
|
||||
s = start_request_session()
|
||||
response = s.get(url)
|
||||
return response.json()
|
||||
|
||||
|
||||
def evaluate_log_file_for_abrupt_stop(log_file):
|
||||
with open(log_file) as f:
|
||||
for i, line in enumerate(f):
|
||||
for sign in SIGNS_OF_STOPPAGE:
|
||||
if sign in line:
|
||||
print(f"Found sign of abrupt stoppage in [line {i}]: '{sign}'")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_ci_specific_run_specific_failure_details(repo_name, run_id):
|
||||
url = f"https://api.github.com/repos/{repo_name}/actions/runs/{run_id}/attempts/1/logs"
|
||||
s = start_request_session()
|
||||
response = s.get(url)
|
||||
|
||||
# SAVE zip file
|
||||
with open("logs.zip", "wb") as f:
|
||||
f.write(response.content)
|
||||
|
||||
# unzip file
|
||||
with zipfile.ZipFile("logs.zip", "r") as zip_ref:
|
||||
zip_ref.extractall("logs")
|
||||
|
||||
failed_logs = []
|
||||
for file in pathlib.Path("logs").iterdir():
|
||||
if file.is_dir():
|
||||
continue
|
||||
|
||||
if evaluate_log_file_for_abrupt_stop(file):
|
||||
failed_logs.append(file)
|
||||
|
||||
return failed_logs
|
||||
|
||||
|
||||
def restart_job(repo_name, job_id):
|
||||
url = f"https://api.github.com/repos/{repo_name}/actions/runs/{job_id}/rerun-failed-jobs"
|
||||
s = start_request_session()
|
||||
response = s.post(url)
|
||||
return response.json()
|
||||
|
||||
|
||||
def eval_jobs():
|
||||
run = get_ci_run(REPO_OWNER, WORKFLOW_RUN_ID)
|
||||
if run["run_attempt"] > 1:
|
||||
print("This is not the first attempt. Exiting")
|
||||
return
|
||||
failed_logs = get_ci_specific_run_specific_failure_details(REPO_OWNER, WORKFLOW_RUN_ID)
|
||||
|
||||
if len(failed_logs) == 0:
|
||||
print("No runs exhibit signs of abrupt stoppage")
|
||||
return
|
||||
|
||||
print("restarting job", WORKFLOW_RUN_ID)
|
||||
r = restart_job(REPO_OWNER, WORKFLOW_RUN_ID)
|
||||
print(r)
|
||||
|
||||
shutil.rmtree("logs")
|
||||
os.remove("logs.zip")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
eval_jobs()
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2 # https://github.com/actions/setup-python
|
||||
with:
|
||||
python-version: '3.7.7' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
python-version: '3.10.9' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
- run: echo ${{ env.DATE }}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pyver: [py37, py39, py310]
|
||||
pyver: [py39, py310]
|
||||
config:
|
||||
- {
|
||||
name: "Windows Build",
|
||||
@@ -61,8 +61,8 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2 # https://github.com/actions/setup-python
|
||||
with:
|
||||
python-version: '3.7.7' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
python-version: '3.10'
|
||||
- run: echo ${{ env.DATE }}
|
||||
- name: Get current date
|
||||
id: date
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
name: ci-ifcopenshell-conda-daily
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["ci"]
|
||||
types:
|
||||
- completed
|
||||
push:
|
||||
paths:
|
||||
- .github/workflows/ci-ifcopenshell-conda-daily.yml
|
||||
- conda/**
|
||||
schedule:
|
||||
# ┌───────────── minute (0 - 59)
|
||||
# │ ┌───────────── hour (0 - 23)
|
||||
# │ │ ┌───────────── day of the month (1 - 31)
|
||||
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
|
||||
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
|
||||
# * * * * *
|
||||
- cron: "49 23 * * *" # 11min before utc midnight every day
|
||||
|
||||
jobs:
|
||||
activate:
|
||||
@@ -26,20 +34,16 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pyver: [
|
||||
# { name: py39, distver: '3.9' },
|
||||
{ name: py310, distver: '3.10'},
|
||||
{ name: py311, distver: '3.11'}
|
||||
]
|
||||
platform: [
|
||||
{ name: Windows, distver: windows-2022, upload: 'false' },
|
||||
{ name: Windows, distver: windows-2019, upload: 'true' },
|
||||
{ name: Linux, distver: ubuntu-20.04, upload: 'true' },
|
||||
{ name: Linux, distver: ubuntu-22.04, upload: 'false' },
|
||||
{ name: macOS, distver: macos-11, upload: 'true' },
|
||||
{ name: macOS, distver: macos-12, upload: 'false' }
|
||||
{ name: Windows, distver: windows-2022, upload: 'true' },
|
||||
{ name: Linux, distver: ubuntu-22.04, upload: 'true' },
|
||||
{ name: macOS, distver: macos-12, upload: 'true' }
|
||||
]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Download MacOSX SDK
|
||||
@@ -50,16 +54,20 @@ jobs:
|
||||
sudo mv -v MacOSX10.13.sdk /opt/ && \
|
||||
ls /opt/
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- uses: conda-incubator/setup-miniconda@v2 # https://github.com/conda-incubator/setup-miniconda
|
||||
- uses: mamba-org/provision-with-micromamba@main # https://github.com/mamba-org/provision-with-micromamba
|
||||
with:
|
||||
activate-environment: conda-build
|
||||
python-version: ${{ matrix.pyver.distver }}
|
||||
channels: conda-forge
|
||||
channel-priority: strict
|
||||
environment-file: conda/environment.yml
|
||||
extra-specs: |
|
||||
python=${{ matrix.pyver.distver }}
|
||||
- name: build, test and upload ifcopenshell
|
||||
if: ${{ matrix.platform.upload == 'true' }}
|
||||
run: |
|
||||
conda-build . --python ${{ matrix.pyver.distver }} -c conda-forge --token ${{ secrets.ANACONDA_TOKEN }} --user ifcopenshell --no-remove-work-dir
|
||||
conda-build . --python ${{ matrix.pyver.distver }} -c conda-forge --token ${{ secrets.ANACONDA_TOKEN }} --user ifcopenshell
|
||||
working-directory: ./conda
|
||||
- name: build & test ifcopenshell
|
||||
if: ${{ matrix.platform.upload == 'false' }}
|
||||
run: |
|
||||
conda-build . --python ${{ matrix.pyver.distver }} -c conda-forge --no-remove-work-dir
|
||||
conda-build . --python ${{ matrix.pyver.distver }} -c conda-forge
|
||||
working-directory: ./conda
|
||||
|
||||
@@ -8,7 +8,11 @@ on:
|
||||
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
|
||||
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
|
||||
# * * * * *
|
||||
- cron: "49 23 1 * *" # 11min before utc midnight
|
||||
- cron: "0 0 18 * *"
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/ci-ifcopenshell-pypi.yml'
|
||||
|
||||
|
||||
env:
|
||||
major: 0
|
||||
@@ -31,7 +35,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pyver: [py36, py37, py38, py39, py310]
|
||||
pyver: [py36, py37, py38, py39, py310, py311]
|
||||
config:
|
||||
- {
|
||||
name: "Windows Build",
|
||||
@@ -53,7 +57,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2 # https://github.com/actions/setup-python
|
||||
with:
|
||||
python-version: '3.7.7' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
python-version: '3.10' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
- run: echo ${{ env.DATE }}
|
||||
- name: Get current date
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
name: ci-ifctester-pypi
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# ┌───────────── minute (0 - 59)
|
||||
# │ ┌───────────── hour (0 - 23)
|
||||
# │ │ ┌───────────── day of the month (1 - 31)
|
||||
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
|
||||
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
|
||||
# * * * * *
|
||||
- cron: "0 0 18 * *"
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/ci-ifctester-pypi.yml'
|
||||
|
||||
|
||||
env:
|
||||
major: 0
|
||||
minor: 0
|
||||
name: ifcopenshell
|
||||
|
||||
jobs:
|
||||
activate:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.repository == 'IfcOpenShell/IfcOpenShell'
|
||||
steps:
|
||||
- name: Set env
|
||||
run: echo ok go
|
||||
|
||||
build:
|
||||
needs: activate
|
||||
name: ${{ matrix.config.name }}-${{ matrix.pyver }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2 # https://github.com/actions/setup-python
|
||||
with:
|
||||
python-version: '3.10' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
- run: echo ${{ env.DATE }}
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: echo "::set-output name=date::$(date +'%y%m%d')"
|
||||
- name: Compile
|
||||
run: |
|
||||
pip install build
|
||||
cd src/ifctester &&
|
||||
make dist
|
||||
- name: Publish a Python distribution to PyPI
|
||||
uses: ortega2247/pypi-upload-action@master
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
packages_dir: src/ifctester/dist
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
- 'test/**'
|
||||
- 'conda/**'
|
||||
- 'cmake/**'
|
||||
- '.github/workflows/ci_py_only.yml'
|
||||
- '.github/workflows/ci-py-only.yml'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
@@ -46,13 +46,14 @@ jobs:
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${GITHUB_WORKFLOW}
|
||||
|
||||
- name: Build ifcopenshell
|
||||
run: |
|
||||
sudo /usr/sbin/update-ccache-symlinks
|
||||
mkdir build && cd build
|
||||
cmake \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
PATH="/usr/lib/ccache:$PATH" cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_PREFIX_PATH=/usr \
|
||||
-DCMAKE_SYSTEM_PREFIX_PATH=/usr \
|
||||
@@ -62,7 +63,7 @@ jobs:
|
||||
-DPYTHON_INCLUDE_DIR:PATH=/usr/include/python3.8 \
|
||||
-DPYTHON_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libpython3.8.so \
|
||||
-DCOLLADA_SUPPORT=Off \
|
||||
"-DSCHEMA_VERSIONS=2x3;4" \
|
||||
"-DSCHEMA_VERSIONS=2x3;4;4x3_add1" \
|
||||
-DBUILD_CONVERT=Off \
|
||||
-DGLTF_SUPPORT=On \
|
||||
-DJSON_INCLUDE_DIR=/usr/include \
|
||||
@@ -79,12 +80,14 @@ jobs:
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
sudo /usr/bin/python -m pip install -U pip
|
||||
sudo /usr/bin/python -m pip install xmlschema numpy lxml
|
||||
sudo /usr/bin/python -m pip install src/bcf
|
||||
sudo /usr/bin/python -m pip install xmlschema xsdata numpy lxml
|
||||
sudo /usr/bin/python -m pip install src/bcf --no-deps
|
||||
sudo /usr/bin/python -m pip install pytest
|
||||
sudo /usr/bin/python -m pip install isodate
|
||||
sudo /usr/bin/python -m pip install lark
|
||||
sudo /usr/bin/python -m pip install networkx
|
||||
sudo /usr/bin/python -m pip install tabulate
|
||||
sudo /usr/bin/python -m pip install python-dateutil
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Restart failed daily conda builds
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [ ci-ifcopenshell-conda-daily ]
|
||||
types:
|
||||
- completed
|
||||
|
||||
env:
|
||||
REPO_OWNER: IfcOpenShell/IfcOpenShell
|
||||
MY_WORKFLOW: ci-ifcopenshell-conda-daily
|
||||
|
||||
jobs:
|
||||
restart-failed-runs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Use python 3.11
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.11
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install requests
|
||||
- name: Check for failed runs
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
run: |
|
||||
python check_repo_ci_jobs.py
|
||||
working-directory: .github/workflows
|
||||
@@ -57,6 +57,8 @@ jobs:
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${GITHUB_WORKFLOW}
|
||||
|
||||
- name: Build ifcopenshell
|
||||
run: |
|
||||
@@ -73,7 +75,7 @@ jobs:
|
||||
-DPYTHON_INCLUDE_DIR:PATH=/usr/include/python3.8 \
|
||||
-DPYTHON_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libpython3.8.so \
|
||||
-DCOLLADA_SUPPORT=Off \
|
||||
"-DSCHEMA_VERSIONS=2x3;4;4x3" \
|
||||
"-DSCHEMA_VERSIONS=2x3;4;4x3_add1" \
|
||||
-DGLTF_SUPPORT=On \
|
||||
-DJSON_INCLUDE_DIR=/usr/include \
|
||||
-DCGAL_INCLUDE_DIR=/usr/include \
|
||||
@@ -86,15 +88,32 @@ jobs:
|
||||
sudo make -j $(nproc)
|
||||
sudo make install
|
||||
|
||||
- name: Run IfcConvert on Sample files
|
||||
run: |
|
||||
(find test/input src/blenderbim/test/files -name '*.ifc' | while read i; do \
|
||||
echo $i | tee -a log; \
|
||||
timeout 1m "$(which IfcConvert)" -yv "$i" "$i.obj" --validate >> log 2>&1; \
|
||||
echo $i $? >> statuses; \
|
||||
done) || true
|
||||
echo Failed
|
||||
grep -v 0$ statuses
|
||||
grep -v 0$ statuses | wc -l
|
||||
echo Succeeded
|
||||
grep 0$ statuses
|
||||
grep 0$ statuses | wc -l
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
sudo /usr/bin/python -m pip install -U pip
|
||||
sudo /usr/bin/python -m pip install xmlschema numpy lxml
|
||||
sudo /usr/bin/python -m pip install src/bcf
|
||||
sudo /usr/bin/python -m pip install xmlschema xsdata numpy lxml
|
||||
sudo /usr/bin/python -m pip install src/bcf --no-deps
|
||||
sudo /usr/bin/python -m pip install pytest
|
||||
sudo /usr/bin/python -m pip install isodate
|
||||
sudo /usr/bin/python -m pip install lark
|
||||
sudo /usr/bin/python -m pip install networkx
|
||||
sudo /usr/bin/python -m pip install https://github.com/Andrej730/aud/archive/refs/heads/master-reduced-size.zip
|
||||
sudo /usr/bin/python -m pip install tabulate
|
||||
sudo /usr/bin/python -m pip install python-dateutil
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
|
||||
@@ -77,3 +77,24 @@ src/ifcopenshell-python/test/build
|
||||
# tox cache
|
||||
.tox/
|
||||
*.egg-info/
|
||||
|
||||
# mypy cache
|
||||
.mypy_cache
|
||||
|
||||
# blenderbim libs
|
||||
src/blenderbim/blenderbim/libs
|
||||
|
||||
# blenderbim test temp files
|
||||
src/blenderbim/test/files/temp
|
||||
src/blenderbim/drawings
|
||||
src/blenderbim/layouts
|
||||
|
||||
# ifcopenshell swig and compiled files
|
||||
src/ifcopenshell-python/ifcopenshell/_ifcopenshell_wrapper.so
|
||||
src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.py
|
||||
|
||||
# apple
|
||||
.DS_Store
|
||||
|
||||
# Brickschema
|
||||
src/blenderbim/blenderbim/bim/schema/Brick.ttl
|
||||
@@ -1,81 +0,0 @@
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
cache: ccache
|
||||
os: linux
|
||||
dist: focal
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages:
|
||||
- libboost-date-time-dev
|
||||
- libboost-filesystem-dev
|
||||
- libboost-iostreams-dev
|
||||
- libboost-program-options-dev
|
||||
- libboost-regex-dev
|
||||
- libboost-system-dev
|
||||
- libboost-thread-dev
|
||||
- libocct-data-exchange-dev
|
||||
- libocct-foundation-dev
|
||||
- libocct-modeling-algorithms-dev
|
||||
- libocct-modeling-data-dev
|
||||
- libxml2-dev
|
||||
- nlohmann-json3-dev
|
||||
- opencollada-dev
|
||||
- python3-all-dev
|
||||
- python3-pip
|
||||
- swig
|
||||
- libhdf5-dev
|
||||
|
||||
before_script:
|
||||
- if [ $TRAVIS_OS_NAME == "linux" ]; then ccache -z; fi
|
||||
|
||||
install:
|
||||
# for IDS
|
||||
- python3 -m pip install xmlschema
|
||||
|
||||
script:
|
||||
- pwd
|
||||
- mkdir build && cd build
|
||||
- |
|
||||
cmake \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DOCC_INCLUDE_DIR=/usr/include/opencascade \
|
||||
-DOCC_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu \
|
||||
-DPYTHON_EXECUTABLE:FILEPATH=/usr/bin/python3 \
|
||||
-DPYTHON_INCLUDE_DIR:PATH=/usr/include/python3.8 \
|
||||
-DPYTHON_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libpython3.8.so \
|
||||
"-DSCHEMA_VERSIONS=2x3;4" \
|
||||
-DGLTF_SUPPORT=On \
|
||||
-DJSON_INCLUDE_DIR=/usr/include \
|
||||
-DHDF5_INCLUDE_DIR=/usr/include/hdf5/serial \
|
||||
../cmake
|
||||
|
||||
# TODO: Drop sudo
|
||||
- sudo make -j $(nproc) install
|
||||
|
||||
- cd ../test
|
||||
- /usr/bin/python tests.py
|
||||
- /usr/bin/python ../src/ifcopenshell-python/ifcopenshell/test_ids.py
|
||||
|
||||
- cd input
|
||||
|
||||
- /usr/local/bin/IfcConvert -yv acad2010_walls.ifc acad2010_walls.glb
|
||||
|
||||
- /usr/bin/python -c "from io import open; import ifcopenshell; f = ifcopenshell.open('encoding.ifc'); assert list(map(ord, f[1][0])) == [39, 97, 39, 32, 49, 109, 179, 32, 8804, 32, 53, 109, 179, 32, 8805, 32, 49, 48, 109, 179]"
|
||||
|
||||
- |
|
||||
(for i in *.ifc; do \
|
||||
echo $i | tee -a log; \
|
||||
timeout 1m /usr/local/bin/IfcConvert -yv "$i" "$i.dae" --validate >> log 2>&1; \
|
||||
echo $i $? >> statuses; \
|
||||
done) || true
|
||||
- echo Failed
|
||||
- grep -v 0$ statuses
|
||||
- grep -v 0$ statuses | wc -l
|
||||
- echo Succeeded
|
||||
- grep 0$ statuses
|
||||
- grep 0$ statuses | wc -l
|
||||
|
||||
after_script:
|
||||
- if [ $TRAVIS_OS_NAME == "linux" ]; then ccache -s; fi
|
||||
@@ -27,7 +27,7 @@ RUN echo "deb http://archive.ubuntu.com/ubuntu focal-proposed main restricted" |
|
||||
libboost-all-dev \
|
||||
libocct-foundation-dev libocct-modeling-algorithms-dev libocct-modeling-data-dev \
|
||||
libocct-ocaf-dev libocct-visualization-dev libocct-data-exchange-dev \
|
||||
libhdf5-serial-dev ; \
|
||||
libhdf5-serial-dev python3-pytest ; \
|
||||
rm -rf /var/lib/apt/lists/* ;
|
||||
|
||||
COPY . /home/IfcOpenShell/
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
|
||||
IfcOpenShell
|
||||
============
|
||||
<p align="center">
|
||||
<img src="https://github.com/IfcOpenShell/IfcOpenShell/assets/79010126/9e540403-c79f-446a-88c6-7c1ebc6ba864">
|
||||
</p>
|
||||
|
||||
IfcOpenShell is an open source ([LGPL]) software library for working with Industry Foundation Classes ([IFC]). Complete
|
||||
parsing support is provided for [IFC2x3 TC1], [IFC4 Add2 TC1], IFC4x1, IFC4x3, and IFC4x3. Extensive geometric support
|
||||
parsing support is provided for [IFC2x3 TC1], [IFC4 Add2 TC1], IFC4x1, IFC4x2, and IFC4x3. Extensive geometric support
|
||||
is implemented for the IFC releases [IFC2x3 TC1] and [IFC4 Add2 TC1]. Extending with support for arbitrary IFC schemas
|
||||
is possible at compile-time when using C++ and at run-time when using Python.
|
||||
|
||||
@@ -28,7 +31,8 @@ For more information, see:
|
||||
| Anaconda Daily Build | [](https://anaconda.org/ifcopenshell/ifcopenshell) |
|
||||
| Anaconda v0.7.0 Stable | [](https://anaconda.org/conda-forge/ifcopenshell) |
|
||||
| PyPi Daily Build | [](https://pypi.org/project/ifcopenshell/) |
|
||||
| ArchLinux AUR Package | [](https://aur.archlinux.org/packages/ifcopenshell-git) |
|
||||
| ArchLinux AUR Package Stable | [](https://aur.archlinux.org/packages/ifcopenshell) |
|
||||
| ArchLinux AUR Package git | [](https://aur.archlinux.org/packages/ifcopenshell-git) |
|
||||
| BlenderBIM Add-on Chocolatey (under moderation) | [](https://community.chocolatey.org/packages/blenderbim-nightly/) |
|
||||
| Sponsor development on OpenCollective | [](https://opencollective.com/opensourcebim/) |
|
||||
| Docker hub | [](https://hub.docker.com/r/aecgeeks/ifcopenshell) |
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Dockerfile for Running AWS Lambda Function with Python and IfcOpenShell
|
||||
|
||||
# Base image: Python 3.9 from AWS's public container registry
|
||||
FROM public.ecr.aws/docker/library/python:3.9 AS build
|
||||
|
||||
# Set the location of your Lambda function code
|
||||
ARG FUNCTION_DIR="/var/task"
|
||||
|
||||
# Install necessary packages
|
||||
RUN apt-get -y update && apt-get -y install unzip curl
|
||||
|
||||
# Install AWS Lambda runtime interface client
|
||||
RUN pip install --target ${FUNCTION_DIR} awslambdaric
|
||||
|
||||
# Set the IfcOpenShell build version (check available builds at: https://blenderbim.org/docs-python/ifcopenshell-python/installation.html)
|
||||
ARG IFC_OPENSHELL_BUILD="39-v0.7.0-476ab50"
|
||||
|
||||
# Download and extract IfcOpenShell
|
||||
RUN curl https://s3.amazonaws.com/ifcopenshell-builds/ifcopenshell-python-${IFC_OPENSHELL_BUILD}-linux64.zip -O && \
|
||||
unzip ifcopenshell-python-${IFC_OPENSHELL_BUILD}-linux64.zip && \
|
||||
mv ifcopenshell ${FUNCTION_DIR} && \
|
||||
rm ifcopenshell-python-${IFC_OPENSHELL_BUILD}-linux64.zip
|
||||
|
||||
# Copy the requirements file and install dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
# Copy the Lambda function code
|
||||
COPY ./example_handler ${FUNCTION_DIR}/example_handler
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR ${FUNCTION_DIR}
|
||||
|
||||
# Set the entrypoint for the Lambda function
|
||||
ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
|
||||
|
||||
# Set the Python import path to the Lambda function handler
|
||||
# This path is relative to the root of the Lambda function code (FUNCTION_DIR)
|
||||
# Lambda invocation will look for this path
|
||||
CMD ["example_handler.extract_wall_psets_handler"]
|
||||
@@ -0,0 +1,27 @@
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
import boto3
|
||||
|
||||
s3 = boto3.client('s3')
|
||||
|
||||
def extract_wall_psets_handler(event, context):
|
||||
print("Hello from lambda")
|
||||
print("Event: {}".format(event))
|
||||
print("Context: {}".format(context))
|
||||
|
||||
filename = event['body']['filename']
|
||||
|
||||
s3.download_file('my_ifc_files_bucket', filename, f'/tmp/{filename}')
|
||||
ifc_file = ifcopenshell.open(f'/tmp/{filename}')
|
||||
walls = ifc_file.by_type('IfcWall')
|
||||
|
||||
psets = []
|
||||
for wall in walls:
|
||||
wall_data = ifcopenshell.util.element.get_psets(wall)
|
||||
wall_data['id'] = wall.GlobalId
|
||||
psets.append(wall_data)
|
||||
|
||||
return {
|
||||
'statusCode': 200,
|
||||
'body': psets
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
boto3
|
||||
@@ -21,7 +21,7 @@ cmake_minimum_required(VERSION 3.1.3)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON) # not necessary, but encouraged
|
||||
|
||||
project (IfcOpenShell VERSION 0.7.0)
|
||||
project(IfcOpenShell VERSION 0.7.0)
|
||||
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
@@ -54,11 +54,14 @@ OPTION(USE_VLD "Use Visual Leak Detector for debugging memory leaks, MSVC-only."
|
||||
OPTION(USE_MMAP "Adds a command line options to parse IFC files from memory mapped files using Boost.Iostreams" OFF)
|
||||
OPTION(BUILD_SHARED_LIBS "Build IfcParse and IfcGeom as shared libs (SO/DLL)." OFF)
|
||||
OPTION(MSVC_PARALLEL_BUILD "Multi-threaded compilation in Microsoft Visual Studio (/MP)" OFF)
|
||||
OPTION(NO_WARN "Disable all warnings" OFF)
|
||||
OPTION(WASM_BUILD OFF)
|
||||
if (${HAS_MAX})
|
||||
OPTION(BUILD_IFCMAX "Build IfcMax, a 3ds Max plug-in, Windows-only." OFF)
|
||||
endif()
|
||||
if (${BUILD_CONVERT})
|
||||
OPTION(GLTF_SUPPORT "Build IfcConvert with glTF support (requires json.hpp)." OFF)
|
||||
OPTION(USD_SUPPORT "Build IfcConvert with USD support (requires pixar's USD library)." OFF)
|
||||
endif()
|
||||
OPTION(USERSPACE_PYTHON_PREFIX "Installs IfcPython for the current user only instead of system-wide." OFF)
|
||||
OPTION(ADD_COMMIT_SHA "Add commit sha and branch in version number, warning results in many rebuilds, requires git" OFF)
|
||||
@@ -71,6 +74,14 @@ if(MSVC AND MSVC_PARALLEL_BUILD)
|
||||
add_definitions("/MP")
|
||||
endif()
|
||||
|
||||
if(NO_WARN)
|
||||
if(MSVC)
|
||||
add_compile_options("/w")
|
||||
else()
|
||||
add_compile_options("-w")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# QtViewer requires Qt5
|
||||
OPTION(BUILD_QTVIEWER "Build IfcOpenShell Qt GUI Viewer" OFF)
|
||||
include(GNUInstallDirs)
|
||||
@@ -136,11 +147,6 @@ UNIFY_ENVVARS_AND_CACHE(PYTHON_EXECUTABLE)
|
||||
UNIFY_ENVVARS_AND_CACHE(HDF5_INCLUDE_DIR)
|
||||
UNIFY_ENVVARS_AND_CACHE(HDF5_LIBRARY_DIR)
|
||||
UNIFY_ENVVARS_AND_CACHE(HDF5_LIBRARIES)
|
||||
endif()
|
||||
UNIFY_ENVVARS_AND_CACHE(BOOST_ROOT)
|
||||
UNIFY_ENVVARS_AND_CACHE(BOOST_LIBRARYDIR)
|
||||
|
||||
if (NOT MINIMAL_BUILD)
|
||||
UNIFY_ENVVARS_AND_CACHE(CGAL_INCLUDE_DIR)
|
||||
UNIFY_ENVVARS_AND_CACHE(CGAL_LIBRARY_DIR)
|
||||
UNIFY_ENVVARS_AND_CACHE(GMP_INCLUDE_DIR)
|
||||
@@ -148,6 +154,16 @@ UNIFY_ENVVARS_AND_CACHE(GMP_LIBRARY_DIR)
|
||||
UNIFY_ENVVARS_AND_CACHE(MPFR_INCLUDE_DIR)
|
||||
UNIFY_ENVVARS_AND_CACHE(MPFR_LIBRARY_DIR)
|
||||
endif()
|
||||
UNIFY_ENVVARS_AND_CACHE(BOOST_ROOT)
|
||||
UNIFY_ENVVARS_AND_CACHE(BOOST_LIBRARYDIR)
|
||||
|
||||
if(WASM_BUILD)
|
||||
# when using the nix/build-all.py build script we should not
|
||||
# look into the sysroot for most of the dependencies but rather
|
||||
# in the designated build/ folder created by the script.
|
||||
set(CMAKE_FIND_ROOT_PATH_BACKUP "${CMAKE_FIND_ROOT_PATH}")
|
||||
set(CMAKE_FIND_ROOT_PATH "")
|
||||
endif()
|
||||
|
||||
if (NOT MINIMAL_BUILD AND GLTF_SUPPORT AND BUILD_CONVERT)
|
||||
UNIFY_ENVVARS_AND_CACHE(JSON_INCLUDE_DIR)
|
||||
@@ -161,6 +177,54 @@ add_definitions(-DWITH_GLTF)
|
||||
set(SWIG_DEFINES ${SWIG_DEFINES} -DWITH_GLTF)
|
||||
endif()
|
||||
|
||||
# Add USD support to serializers
|
||||
if(NOT MINIMAL_BUILD AND USD_SUPPORT)
|
||||
UNIFY_ENVVARS_AND_CACHE(USD_INCLUDE_DIR)
|
||||
UNIFY_ENVVARS_AND_CACHE(USD_LIBRARY_DIR)
|
||||
|
||||
if("${USD_INCLUDE_DIR}" STREQUAL "")
|
||||
find_path(USD_INCLUDE_DIR pxr.h
|
||||
[PATHS
|
||||
/usr/include/pxr
|
||||
/usr/local/include/pxr
|
||||
]
|
||||
REQUIRED
|
||||
)
|
||||
if(USD_INCLUDE_DIR)
|
||||
message(STATUS "Found USD include files in: ${USD_INCLUDE_DIR}")
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to find USD include directory, specify USD_INCLUDE_DIR manually.")
|
||||
endif()
|
||||
else()
|
||||
set(USD_INCLUDE_DIR ${USD_INCLUDE_DIR} CACHE FILEPATH "USD header files")
|
||||
message(STATUS "Looking for USD include files in: ${USD_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
set(USD_LIBRARIES
|
||||
usd_usd
|
||||
usd_usdGeom
|
||||
usd_usdShade
|
||||
usd_usdLux
|
||||
usd_vt
|
||||
usd_sdf
|
||||
usd_tf
|
||||
usd_gf
|
||||
)
|
||||
|
||||
find_library(USD_LIBRARY
|
||||
NAMES ${USD_LIBRARIES}
|
||||
PATHS ${USD_LIBRARY_DIR})
|
||||
if(USD_LIBRARY)
|
||||
message(STATUS "USD libraries ${USD_LIBRARIES} found in: ${USD_LIBRARY_DIR}")
|
||||
link_directories(${USD_LIBRARY_DIR})
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to find USD libraries in: ${USD_LIBRARY_DIR}")
|
||||
endif()
|
||||
|
||||
add_definitions(-DWITH_USD)
|
||||
set(SWIG_DEFINES ${SWIG_DEFINES} -DWITH_USD)
|
||||
endif()
|
||||
|
||||
# Set INSTALL_RPATH for target
|
||||
MACRO(SET_INSTALL_RPATHS _target _paths)
|
||||
SET(${_target}_rpaths "")
|
||||
@@ -199,7 +263,14 @@ ELSE()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
set(BOOST_COMPONENTS system program_options regex thread date_time)
|
||||
if (WASM_BUILD)
|
||||
set(BOOST_COMPONENTS)
|
||||
else()
|
||||
# @todo review this, shouldn't this be all possible header-only now?
|
||||
# ... or rewritten using C++17 features?
|
||||
set(BOOST_COMPONENTS system program_options regex thread date_time)
|
||||
endif()
|
||||
|
||||
if(USE_MMAP)
|
||||
if(MSVC)
|
||||
# filesystem is necessary for the utf-16 wpath
|
||||
@@ -210,6 +281,10 @@ if(USE_MMAP)
|
||||
add_definitions(-DUSE_MMAP)
|
||||
endif()
|
||||
|
||||
FIND_PACKAGE(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
MESSAGE(STATUS "Boost include files found in ${Boost_INCLUDE_DIRS}")
|
||||
MESSAGE(STATUS "Boost libraries found in ${Boost_LIBRARY_DIRS}")
|
||||
|
||||
if (NOT MINIMAL_BUILD)
|
||||
# libxml2 is required for IFCXML (optional) and SVGFILL (mandatory)
|
||||
find_package(LibXml2 REQUIRED)
|
||||
@@ -220,11 +295,6 @@ if (NOT MINIMAL_BUILD AND IFCXML_SUPPORT)
|
||||
set(SWIG_DEFINES ${SWIG_DEFINES} -DWITH_IFCXML)
|
||||
endif()
|
||||
|
||||
FIND_PACKAGE(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
MESSAGE(STATUS "Boost include files found in ${Boost_INCLUDE_DIRS}")
|
||||
MESSAGE(STATUS "Boost libraries found in ${Boost_LIBRARY_DIRS}")
|
||||
|
||||
|
||||
# Usage:
|
||||
# set(SOME_LIRARIES foo bar)
|
||||
# add_debug_variants(SOME_LIRARIES "${SOME_LIRARIES}" d)
|
||||
@@ -343,10 +413,21 @@ if("${libTKernelExt}" STREQUAL ".a")
|
||||
set(OCCT_STATIC ON)
|
||||
endif()
|
||||
|
||||
if(WASM_BUILD)
|
||||
set(CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH_BACKUP}")
|
||||
endif()
|
||||
|
||||
if(OCCT_STATIC)
|
||||
find_package(Threads)
|
||||
# OPENCASCADE_LIBRARIES repeated three times below in order to fix cyclic dependencies - use --start-group ... --end-group instead?
|
||||
set(OPENCASCADE_LIBRARIES ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
if(WASM_BUILD)
|
||||
set(OPENCASCADE_LIBRARIES ${OPENCASCADE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
else()
|
||||
# OPENCASCADE_LIBRARIES repeated N times below in order to fix cyclic dependencies - use --start-group ... --end-group instead?
|
||||
# tfk: --start-group ... --end-group didn't work on the apple linker when last tested
|
||||
set(OPENCASCADE_LIBRARIES ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
if (NOT APPLE AND NOT WIN32)
|
||||
set(OPENCASCADE_LIBRARIES ${OPENCASCADE_LIBRARIES} "rt")
|
||||
endif()
|
||||
@@ -607,6 +688,7 @@ ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES} ${OCC_INCLUDE_DIR} ${OPENCOLLADA_INCLUDE_DIRS}
|
||||
${Boost_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIR} ${JSON_INCLUDE_DIR} ${HDF5_INCLUDE_DIR}
|
||||
${USD_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
function(files_for_ifc_version IFC_VERSION RESULT_NAME)
|
||||
@@ -620,7 +702,12 @@ function(files_for_ifc_version IFC_VERSION RESULT_NAME)
|
||||
endfunction()
|
||||
|
||||
if(NOT SCHEMA_VERSIONS)
|
||||
set(SCHEMA_VERSIONS "2x3" "4" "4x1" "4x2" "4x3_rc1" "4x3_rc2" "4x3_rc3" "4x3_rc4" "4x3")
|
||||
if(WASM_BUILD)
|
||||
# super arbitrarily try to keep size down at least a little bit
|
||||
set(SCHEMA_VERSIONS "2x3" "4")
|
||||
else()
|
||||
set(SCHEMA_VERSIONS "2x3" "4" "4x1" "4x2" "4x3_rc1" "4x3_rc2" "4x3_rc3" "4x3_rc4" "4x3" "4x3_tc1" "4x3_add1")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(s ${SCHEMA_VERSIONS})
|
||||
@@ -697,7 +784,11 @@ if (BUILD_IFCGEOM)
|
||||
foreach(s ${SCHEMA_VERSIONS})
|
||||
set(IFCGEOM_SCHEMA_LIBRARIES ${IFCGEOM_SCHEMA_LIBRARIES} IfcGeom_ifc${s})
|
||||
endforeach()
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES})
|
||||
if (WASM_BUILD)
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES})
|
||||
else()
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
if (BUILD_CONVERT OR BUILD_IFCPYTHON)
|
||||
foreach(s ${SCHEMA_VERSIONS})
|
||||
@@ -741,7 +832,11 @@ set(IFCPARSE_FILES ${IFCPARSE_CPP_FILES} ${IFCPARSE_H_FILES})
|
||||
add_library(IfcParse ${IFCPARSE_FILES})
|
||||
set_target_properties(IfcParse PROPERTIES COMPILE_FLAGS -DIFC_PARSE_EXPORTS VERSION "0.6.0" SOVERSION "0.6")
|
||||
|
||||
TARGET_LINK_LIBRARIES(IfcParse ${Boost_LIBRARIES} ${BCRYPT_LIBRARIES} ${LIBXML2_LIBRARIES})
|
||||
if (WASM_BUILD)
|
||||
TARGET_LINK_LIBRARIES(IfcParse ${BCRYPT_LIBRARIES} ${LIBXML2_LIBRARIES})
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES(IfcParse ${Boost_LIBRARIES} ${BCRYPT_LIBRARIES} ${LIBXML2_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (BUILD_IFCGEOM)
|
||||
|
||||
@@ -753,7 +848,9 @@ set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES})
|
||||
foreach(s ${SCHEMA_VERSIONS})
|
||||
add_library(IfcGeom_ifc${s} STATIC ${IFCGEOM_FILES})
|
||||
set_target_properties(IfcGeom_ifc${s} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${s}")
|
||||
TARGET_LINK_LIBRARIES(IfcGeom_ifc${s} IfcParse ${OPENCASCADE_LIBRARIES})
|
||||
if (NOT WASM_BUILD)
|
||||
TARGET_LINK_LIBRARIES(IfcGeom_ifc${s} IfcParse ${OPENCASCADE_LIBRARIES})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# IfcGeom (schema agnostic)
|
||||
@@ -768,7 +865,11 @@ if (UNIX)
|
||||
find_package(Threads)
|
||||
endif()
|
||||
|
||||
TARGET_LINK_LIBRARIES(IfcGeom IfcParse ${IFCGEOM_SCHEMA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
if (WASM_BUILD)
|
||||
TARGET_LINK_LIBRARIES(IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES(IfcGeom IfcParse ${IFCGEOM_SCHEMA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
endif(BUILD_IFCGEOM)
|
||||
|
||||
@@ -785,15 +886,20 @@ set(SERIALIZERS_S_FILES ${SERIALIZERS_S_H_FILES} ${SERIALIZERS_S_CPP_FILES})
|
||||
foreach(s ${SCHEMA_VERSIONS})
|
||||
add_library(Serializers_ifc${s} STATIC ${SERIALIZERS_S_FILES})
|
||||
set_target_properties(Serializers_ifc${s} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${s} ${CONVERT_PRECISION}")
|
||||
TARGET_LINK_LIBRARIES(Serializers_ifc${s} IfcGeom ${OPENCASCADE_LIBRARIES} ${HDF5_LIBRARIES})
|
||||
|
||||
if (WASM_BUILD)
|
||||
TARGET_LINK_LIBRARIES(Serializers_ifc${s} ${HDF5_LIBRARIES})
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES(Serializers_ifc${s} IfcGeom ${OPENCASCADE_LIBRARIES} ${HDF5_LIBRARIES})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_library(Serializers ${SERIALIZERS_FILES})
|
||||
set_target_properties(Serializers PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS ${CONVERT_PRECISION}" VERSION "0.6.0" SOVERSION "0.6")
|
||||
|
||||
TARGET_LINK_LIBRARIES(Serializers ${SERIALIZER_SCHEMA_LIBRARIES} ${OPENCOLLADA_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(Serializers ${SERIALIZER_SCHEMA_LIBRARIES} ${OPENCOLLADA_LIBRARIES} ${USD_LIBRARIES})
|
||||
|
||||
endif(BUILD_CONVERT or BUILD_IFCPYTHON)
|
||||
endif(BUILD_CONVERT OR BUILD_IFCPYTHON)
|
||||
|
||||
if (BUILD_CONVERT)
|
||||
|
||||
@@ -804,7 +910,7 @@ set(IFCCONVERT_FILES ${IFCCONVERT_CPP_FILES} ${IFCCONVERT_H_FILES})
|
||||
ADD_EXECUTABLE(IfcConvert ${IFCCONVERT_FILES})
|
||||
set_target_properties(IfcConvert PROPERTIES COMPILE_FLAGS "${CONVERT_PRECISION}")
|
||||
|
||||
TARGET_LINK_LIBRARIES(IfcConvert ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${HDF5_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(IfcConvert ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${HDF5_LIBRARIES} ${USD_LIBRARIES})
|
||||
|
||||
if ((NOT WIN32) AND BUILD_SHARED_LIBS)
|
||||
# Only set RPATHs when building shared libraries (i.e. IfcParse and
|
||||
@@ -847,7 +953,7 @@ find_package (Git)
|
||||
if (GIT_FOUND)
|
||||
message("git found: ${GIT_EXECUTABLE} with version ${GIT_VERSION_STRING}")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} branch --contains HEAD
|
||||
COMMAND ${GIT_EXECUTABLE} branch -a --contains HEAD
|
||||
OUTPUT_VARIABLE git_branches
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
@@ -856,7 +962,8 @@ if (GIT_FOUND)
|
||||
string(REPLACE "*" "" git_branch_candidate_temp "${git_branch_candidate}")
|
||||
string(STRIP "${git_branch_candidate_temp}" git_branch_candidate_2)
|
||||
if (NOT git_branch_candidate_2 MATCHES "^HEAD$")
|
||||
set(git_branch ${git_branch_candidate_2})
|
||||
string(REPLACE "/" ";" git_branch_candidate_2_list "${git_branch_candidate_2}")
|
||||
list(GET git_branch_candidate_2_list -1 git_branch)
|
||||
endif()
|
||||
endforeach()
|
||||
execute_process(
|
||||
@@ -967,7 +1074,7 @@ endforeach(COMPONENT)
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_NAME "${PROJECT_NAME}")
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_CONTACT}")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "python3, libxml2, libocct-foundation-dev, libocct-modeling-algorithms-dev, libocct-modeling-data-dev, libocct-ocaf-dev, libocct-visualization-dev, libocct-data-exchange-dev, libhdf5-serial-dev, libpython3.8 ${BOOST_DEPS}")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "python3, libxml2, libocct-foundation-dev, libocct-modeling-algorithms-dev, libocct-modeling-data-dev, libocct-ocaf-dev, libocct-visualization-dev, libocct-data-exchange-dev, libhdf5-serial-dev, libpython3.8, python3-pytest ${BOOST_DEPS}")
|
||||
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION_SUMMARY "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
|
||||
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION}")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
|
||||
@@ -41,4 +41,4 @@ cmake -G Ninja \
|
||||
|
||||
ninja
|
||||
|
||||
ninja install
|
||||
ninja install -j 1
|
||||
|
||||
@@ -10,5 +10,4 @@ dependencies:
|
||||
- ripgrep
|
||||
- pip
|
||||
- pip:
|
||||
- --extra-index-url https://lief.s3-website.fr-par.scw.cloud/latest
|
||||
- lief==0.13.0.dev0
|
||||
- lief==0.13
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
{% set name = "ifcopenshell" %}
|
||||
{% set version = "0.7.0" %}
|
||||
{% set occt_version = "7.6.2" %}
|
||||
{% set cgal_cpp_version = "5.3" %}
|
||||
{% set hdf5_version = "1.12.1" %}
|
||||
|
||||
|
||||
package:
|
||||
name: {{ name }}
|
||||
@@ -13,6 +11,7 @@ source:
|
||||
|
||||
build:
|
||||
binary_relocation: false [osx]
|
||||
number: 1
|
||||
|
||||
requirements:
|
||||
build:
|
||||
@@ -25,7 +24,7 @@ requirements:
|
||||
host:
|
||||
- python
|
||||
- boost-cpp
|
||||
- occt
|
||||
- occt ==7.7.0
|
||||
- libxml2
|
||||
- cgal-cpp
|
||||
- hdf5
|
||||
@@ -33,11 +32,12 @@ requirements:
|
||||
- gmp # [unix]
|
||||
- mpir # [win]
|
||||
- nlohmann_json
|
||||
- zlib
|
||||
|
||||
run:
|
||||
- python
|
||||
- boost-cpp
|
||||
- occt
|
||||
- occt ==7.7.0
|
||||
- libxml2
|
||||
- cgal-cpp
|
||||
- hdf5
|
||||
@@ -45,6 +45,7 @@ requirements:
|
||||
- gmp # [unix]
|
||||
- mpir # [win]
|
||||
- nlohmann_json
|
||||
- zlib
|
||||
|
||||
test:
|
||||
imports:
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
# * cmake * git * bzip2 * tar * c(++) compilers * autoconf #
|
||||
# #
|
||||
# if building with USE_OCCT additionally: #
|
||||
# * freetype * glx.h #
|
||||
# * glx.h #
|
||||
# #
|
||||
# if building with OCCT 7.4.0 additionally: #
|
||||
# * libfontconfig1-dev #
|
||||
@@ -39,14 +39,14 @@
|
||||
# #
|
||||
# on debian 7.8 these can be obtained with: #
|
||||
# $ apt-get install git gcc g++ autoconf bison bzip2 cmake #
|
||||
# libfreetype6-dev mesa-common-dev libffi-dev libfontconfig1-dev #
|
||||
# mesa-common-dev libffi-dev libfontconfig1-dev #
|
||||
# #
|
||||
# on ubuntu 14.04: #
|
||||
# $ apt-get install git gcc g++ autoconf bison make cmake #
|
||||
# libfreetype6-dev mesa-common-dev libffi-dev libfontconfig1-dev #
|
||||
# mesa-common-dev libffi-dev libfontconfig1-dev #
|
||||
# #
|
||||
# on OS X El Capitan with homebrew: #
|
||||
# $ brew install git bison autoconf automake freetype libffi cmake #
|
||||
# $ brew install git bison autoconf automake libffi cmake #
|
||||
# #
|
||||
###############################################################################
|
||||
import logging
|
||||
@@ -59,6 +59,10 @@ import multiprocessing
|
||||
import platform
|
||||
import sysconfig
|
||||
|
||||
# @todo temporary for expired mpfr.org certificate on 2023-04-08
|
||||
import ssl
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
|
||||
from urllib.request import urlretrieve
|
||||
|
||||
|
||||
@@ -76,7 +80,7 @@ PYTHON_VERSIONS = ["3.6.14", "3.7.13", "3.8.13", "3.9.11", "3.10.3", "3.11.0"]
|
||||
JSON_VERSION = "v3.6.1"
|
||||
OCE_VERSION = "0.18.3"
|
||||
OCCT_VERSION = "7.5.3"
|
||||
BOOST_VERSION = "1.71.0"
|
||||
BOOST_VERSION = "1.80.0"
|
||||
PCRE_VERSION = "8.41"
|
||||
LIBXML2_VERSION = "2.9.11"
|
||||
SWIG_VERSION = "4.0.2"
|
||||
@@ -103,6 +107,9 @@ curl = "curl"
|
||||
wget = "wget"
|
||||
strip = "strip"
|
||||
|
||||
explicit_targets = [s for s in sys.argv[1:] if not s.startswith("-")]
|
||||
flags = set(s.lstrip('-') for s in sys.argv[1:] if s.startswith("-"))
|
||||
|
||||
# Helper function for coloured printing
|
||||
|
||||
NO_COLOR = "\033[0m" # <ref>http://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux</ref>
|
||||
@@ -135,9 +142,11 @@ if platform.system() == "Darwin":
|
||||
|
||||
IFCOS_NUM_BUILD_PROCS = os.getenv("IFCOS_NUM_BUILD_PROCS", multiprocessing.cpu_count() + 1)
|
||||
|
||||
CMAKE_DIR = os.path.realpath(os.path.join("..", "cmake"))
|
||||
CMAKE_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "cmake"))
|
||||
|
||||
path = ["..", "build", platform.system(), platform.machine()]
|
||||
build_dir = os.environ.get("BUILD_DIR", os.path.join(os.path.dirname(__file__), "..", "build"))
|
||||
|
||||
path = [build_dir, platform.system(), "wasm" if "wasm" in flags else platform.machine()]
|
||||
if TOOLSET:
|
||||
path.append(TOOLSET)
|
||||
DEFAULT_DEPS_DIR = os.path.realpath(os.path.join(*path))
|
||||
@@ -186,11 +195,12 @@ dependency_tree = {
|
||||
'boost': (),
|
||||
'libxml2': (),
|
||||
'python': (),
|
||||
'occ': (),
|
||||
'occ': ('freetype',),
|
||||
'pcre': (),
|
||||
'json': (),
|
||||
'hdf5': (),
|
||||
'cgal': ()
|
||||
'cgal': (),
|
||||
'freetype': (),
|
||||
}
|
||||
|
||||
def v(dep):
|
||||
@@ -199,10 +209,12 @@ def v(dep):
|
||||
for x in v(d):
|
||||
yield x
|
||||
|
||||
tgts = [s for s in sys.argv[1:] if not s.startswith("-")]
|
||||
flags = set(s for s in sys.argv[1:] if s.startswith("-"))
|
||||
if "v" in flags:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
else:
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
BUILD_STATIC = not "-shared" in flags
|
||||
BUILD_STATIC = "shared" not in flags
|
||||
ENABLE_FLAG = "--enable-static" if BUILD_STATIC else "--enable-shared"
|
||||
DISABLE_FLAG = "--disable-shared" if BUILD_STATIC else "--disable-static"
|
||||
LINK_TYPE = "static" if BUILD_STATIC else "shared"
|
||||
@@ -210,10 +222,15 @@ LINK_TYPE_UCFIRST = LINK_TYPE[0].upper() + LINK_TYPE[1:]
|
||||
LIBRARY_EXT = "a" if BUILD_STATIC else "so"
|
||||
PIC = "-fPIC" if BUILD_STATIC else ""
|
||||
|
||||
if len(tgts):
|
||||
targets = set(sum((list(v(target)) for target in tgts), []))
|
||||
if any(f.startswith("py-") for f in flags):
|
||||
PYTHON_VERSIONS = [pyv for pyv in PYTHON_VERSIONS if "py-%s" % "".join(pyv.split('.')[0:2]) in flags]
|
||||
|
||||
if len(explicit_targets):
|
||||
targets = set(sum((list(v(target)) for target in explicit_targets), []))
|
||||
else:
|
||||
targets = set(dependency_tree.keys())
|
||||
|
||||
targets = set(t for t in targets if 'without-%s' % t.lower() not in flags)
|
||||
|
||||
print("Building:", *sorted(targets, key=lambda t: len(list(v(t)))))
|
||||
|
||||
@@ -237,7 +254,7 @@ if not os.path.exists(LOG_FILE):
|
||||
open(LOG_FILE, "w").close()
|
||||
logger.info(f"using command log file '{LOG_FILE}'")
|
||||
|
||||
def run(cmds, cwd=None):
|
||||
def run(cmds, cwd=None, can_fail=False):
|
||||
|
||||
"""
|
||||
Wraps `subprocess.Popen.communicate()` and logs the command being executed,
|
||||
@@ -254,7 +271,7 @@ def run(cmds, cwd=None):
|
||||
log_file_handle.close()
|
||||
logger.debug(f"command returned {proc.returncode}")
|
||||
|
||||
if proc.returncode != 0:
|
||||
if proc.returncode != 0 and not can_fail:
|
||||
print("-" * 70)
|
||||
print(stderr)
|
||||
print("-" * 70)
|
||||
@@ -284,7 +301,12 @@ def run_autoconf(arg1, configure_args, cwd):
|
||||
run([bash, "./autogen.sh"], cwd=os.path.realpath(os.path.join(cwd, ".."))) # only run autogen.sh in the directory it is located and use cwd to achieve that in order to not mess up things
|
||||
# Using `sh` over `bash` fixes issues with building swig
|
||||
prefix = os.path.realpath(f"{DEPS_DIR}/install/{arg1}")
|
||||
run(["/bin/sh", "../configure"] + configure_args + [f"--prefix={prefix}"], cwd=cwd)
|
||||
|
||||
wasm = []
|
||||
if "wasm" in flags:
|
||||
wasm.append("emconfigure")
|
||||
|
||||
run([*wasm, "/bin/sh", "../configure"] + configure_args + [f"--prefix={prefix}"], cwd=cwd)
|
||||
|
||||
|
||||
def run_cmake(arg1, cmake_args, cmake_dir=None, cwd=None):
|
||||
@@ -292,7 +314,12 @@ def run_cmake(arg1, cmake_args, cmake_dir=None, cwd=None):
|
||||
P = ".."
|
||||
else:
|
||||
P = cmake_dir
|
||||
run(["cmake", P] + cmake_args + [f"-DCMAKE_BUILD_TYPE={BUILD_CFG}"], cwd=cwd)
|
||||
|
||||
wasm = []
|
||||
if "wasm" in flags:
|
||||
wasm.append("emcmake")
|
||||
|
||||
run([*wasm, "cmake", P, *cmake_args, f"-DCMAKE_BUILD_TYPE={BUILD_CFG}"], cwd=cwd)
|
||||
|
||||
|
||||
def git_clone_or_pull_repository(clone_url, target_dir, revision=None):
|
||||
@@ -374,12 +401,15 @@ def build_dependency(name, mode, build_tool_args, download_url, download_name, d
|
||||
urlretrieve(url, os.path.join(extract_dir, path))
|
||||
|
||||
if patch is not None:
|
||||
patch_abs = os.path.abspath(os.path.join(os.path.dirname(__file__), patch))
|
||||
if os.path.exists(patch_abs):
|
||||
try: run(["patch", "-p1", "--batch", "--forward", "-i", patch_abs], cwd=extract_dir)
|
||||
except Exception as e:
|
||||
# Assert that the patch has already been applied
|
||||
run(["patch", "-p1", "--batch", "--reverse", "--dry-run", "-i", patch_abs], cwd=extract_dir)
|
||||
if isinstance(patch, str):
|
||||
patch = [patch]
|
||||
for p in patch:
|
||||
patch_abs = os.path.abspath(os.path.join(os.path.dirname(__file__), p))
|
||||
if os.path.exists(patch_abs):
|
||||
try: run(["patch", "-p1", "--batch", "--forward", "-i", patch_abs], cwd=extract_dir)
|
||||
except Exception as e:
|
||||
# Assert that the patch has already been applied
|
||||
run(["patch", "-p1", "--batch", "--reverse", "--dry-run", "-i", patch_abs], cwd=extract_dir)
|
||||
|
||||
if mode == "ctest":
|
||||
run(["ctest", "-S", "HDF5config.cmake,BUILD_GENERATOR=Unix", "-C", BUILD_CFG, "-V", "-O", "hdf5.log"], cwd=extract_dir)
|
||||
@@ -410,7 +440,7 @@ def build_dependency(name, mode, build_tool_args, download_url, download_name, d
|
||||
logger.info(f"\rConfiguring {name}...")
|
||||
run([bash, "./bootstrap.sh"], cwd=extract_dir)
|
||||
logger.info(f"\rBuilding {name}... ")
|
||||
run(["./b2", f"-j{IFCOS_NUM_BUILD_PROCS}"] + build_tool_args, cwd=extract_dir)
|
||||
run(["./b2", f"-j{IFCOS_NUM_BUILD_PROCS}"] + build_tool_args, cwd=extract_dir, can_fail="wasm" in flags)
|
||||
logger.info(f"\rInstalling {name}... ")
|
||||
shutil.copytree(os.path.join(extract_dir, "boost"), os.path.join(DEPS_DIR, "install", f"boost-{BOOST_VERSION}", "boost"))
|
||||
logger.info(f"\rInstalled {name} \n")
|
||||
@@ -421,11 +451,13 @@ cecho("Collecting dependencies:", GREEN)
|
||||
# TODO: This is untested
|
||||
|
||||
ADDITIONAL_ARGS = []
|
||||
BOOST_ADDRESS_MODEL = []
|
||||
|
||||
if platform.system() == "Darwin":
|
||||
ADDITIONAL_ARGS = [f"-mmacosx-version-min={TOOLSET}"] + ADDITIONAL_ARGS
|
||||
|
||||
if "wasm" in flags:
|
||||
ADDITIONAL_ARGS.extend(("-sWASM_BIGINT", "-fexceptions"))
|
||||
|
||||
# If the linker supports GC sections, set it up to reduce binary file size
|
||||
# -fPIC is required for the shared libraries to work
|
||||
|
||||
@@ -434,7 +466,7 @@ CFLAGS = os.environ.get("CFLAGS", "")
|
||||
LDFLAGS = os.environ.get("LDFLAGS", "")
|
||||
|
||||
ADDITIONAL_ARGS_STR = " ".join(ADDITIONAL_ARGS)
|
||||
if sp.call([bash, "-c", "ld --gc-sections 2>&1 | grep -- --gc-sections &> /dev/null"]) != 0:
|
||||
if "wasm" not in flags and sp.call([bash, "-c", "ld --gc-sections 2>&1 | grep -- --gc-sections &> /dev/null"]) != 0:
|
||||
CXXFLAGS_MINIMAL = f"{CXXFLAGS} {PIC} {ADDITIONAL_ARGS_STR}"
|
||||
CFLAGS_MINIMAL = f"{CFLAGS} {PIC} {ADDITIONAL_ARGS_STR}"
|
||||
if BUILD_STATIC:
|
||||
@@ -504,8 +536,27 @@ if "swig" in targets:
|
||||
download_tool=download_tool_git,
|
||||
revision=f"rel-{SWIG_VERSION}"
|
||||
)
|
||||
|
||||
if "freetype" in targets:
|
||||
build_dependency(
|
||||
name=f"freetype",
|
||||
mode="cmake",
|
||||
build_tool_args=[
|
||||
f"-DCMAKE_INSTALL_PREFIX={DEPS_DIR}/install/freetype"
|
||||
],
|
||||
download_url = "https://github.com/freetype/freetype",
|
||||
download_name = "freetype2",
|
||||
download_tool=download_tool_git,
|
||||
)
|
||||
|
||||
if USE_OCCT and "occ" in targets:
|
||||
patches = []
|
||||
if OCCT_VERSION < "7.4":
|
||||
patches.append("./patches/occt/enable-exception-handling.patch")
|
||||
|
||||
if "wasm" in flags:
|
||||
patches.append("./patches/occt/no_em_js.patch")
|
||||
|
||||
build_dependency(
|
||||
name=f"occt-{OCCT_VERSION}",
|
||||
mode="cmake",
|
||||
@@ -513,12 +564,13 @@ if USE_OCCT and "occ" in targets:
|
||||
f"-DINSTALL_DIR={DEPS_DIR}/install/occt-{OCCT_VERSION}",
|
||||
f"-DBUILD_LIBRARY_TYPE={LINK_TYPE_UCFIRST}",
|
||||
"-DBUILD_MODULE_Draw=0",
|
||||
"-DBUILD_RELEASE_DISABLE_EXCEPTIONS=Off"
|
||||
"-DBUILD_RELEASE_DISABLE_EXCEPTIONS=Off",
|
||||
f"-D3RDPARTY_FREETYPE_DIR={DEPS_DIR}/install/freetype"
|
||||
],
|
||||
download_url = "https://github.com/Open-Cascade-SAS/OCCT",
|
||||
download_name = "occt",
|
||||
download_tool=download_tool_git,
|
||||
patch=None if OCCT_VERSION >= "7.4" else "./patches/occt/enable-exception-handling.patch",
|
||||
patch=patches,
|
||||
revision="V" + OCCT_VERSION.replace('.', '_')
|
||||
)
|
||||
elif "occ" in targets:
|
||||
@@ -555,6 +607,15 @@ if "libxml2" in targets:
|
||||
)
|
||||
|
||||
if "OpenCOLLADA" in targets:
|
||||
patches = ["./patches/opencollada/pr622_and_disable_subdirs.patch"]
|
||||
|
||||
if "wasm" in flags:
|
||||
# This is necessary for the WASM build, because recent versions of
|
||||
# clang don't have the tr1:: namespace anymore. However, it breaks
|
||||
# some versions of gcc (9.4.0 at least) due to specializing std::hash
|
||||
# outside of the std:: namespace.
|
||||
patches.append("./patches/opencollada/remove_tr1.patch")
|
||||
|
||||
build_dependency(
|
||||
"OpenCOLLADA",
|
||||
"cmake",
|
||||
@@ -569,11 +630,11 @@ if "OpenCOLLADA" in targets:
|
||||
download_url="https://github.com/KhronosGroup/OpenCOLLADA.git",
|
||||
download_name="OpenCOLLADA",
|
||||
download_tool=download_tool_git,
|
||||
patch="./patches/opencollada/pr622_and_disable_subdirs.patch",
|
||||
patch=patches,
|
||||
revision=OPENCOLLADA_VERSION
|
||||
)
|
||||
|
||||
if "python" in targets and not USE_CURRENT_PYTHON_VERSION:
|
||||
if "python" in targets and not USE_CURRENT_PYTHON_VERSION and "wasm" not in flags:
|
||||
# Python should not be built with -fvisibility=hidden, from experience that introduces segfaults
|
||||
OLD_CXX_FLAGS = os.environ["CXXFLAGS"]
|
||||
OLD_C_FLAGS = os.environ["CFLAGS"]
|
||||
@@ -612,6 +673,9 @@ if "python" in targets and not USE_CURRENT_PYTHON_VERSION:
|
||||
|
||||
if "boost" in targets:
|
||||
str_concat = lambda prefix: lambda postfix: "" if postfix.strip() == "" else "=".join((prefix, postfix.strip()))
|
||||
toolset = []
|
||||
if "wasm" in flags:
|
||||
toolset.append("toolset=emscripten")
|
||||
build_dependency(
|
||||
f"boost-{BOOST_VERSION}",
|
||||
mode="bjam",
|
||||
@@ -623,21 +687,30 @@ if "boost" in targets:
|
||||
"--with-thread",
|
||||
"--with-date_time",
|
||||
"--with-iostreams",
|
||||
f"link={LINK_TYPE}"
|
||||
] + \
|
||||
BOOST_ADDRESS_MODEL + \
|
||||
list(map(str_concat("cxxflags"), CXXFLAGS.strip().split(' '))) + \
|
||||
list(map(str_concat("linkflags"), LDFLAGS.strip().split(' '))) + \
|
||||
["stage", "-s", "NO_BZIP2=1"],
|
||||
f"link={LINK_TYPE}",
|
||||
*toolset,
|
||||
*map(str_concat("cxxflags"), CXXFLAGS.strip().split(' ')),
|
||||
*map(str_concat("linkflags"), LDFLAGS.strip().split(' ')),
|
||||
"stage", "-s", "NO_BZIP2=1"],
|
||||
download_url=BOOST_LOCATION,
|
||||
patch="./patches/boost/boostorg_regex_62.patch",
|
||||
download_name=f"boost_{BOOST_VERSION_UNDERSCORE}.tar.bz2"
|
||||
)
|
||||
if "wasm" in flags:
|
||||
# only supported on nix for now
|
||||
run(("find", ".", "-name", "*.bc", "-exec", "bash", "-c", "emar q ${1%.bc}.a $1", "bash", "{}", ";"), cwd=f"{DEPS_DIR}/install/boost-{BOOST_VERSION}/lib")
|
||||
|
||||
if "cgal" in targets:
|
||||
gmp_args = []
|
||||
mpfr_args = []
|
||||
if "wasm" in flags:
|
||||
gmp_args.extend(("--disable-assembly", "--host", "none", "--enable-cxx"))
|
||||
mpfr_args.extend(("--host", "none"))
|
||||
|
||||
build_dependency(
|
||||
name=f"gmp-{GMP_VERSION}",
|
||||
mode="autoconf",
|
||||
build_tool_args=[ENABLE_FLAG, DISABLE_FLAG, "--with-pic"],
|
||||
build_tool_args=[ENABLE_FLAG, DISABLE_FLAG, "--with-pic", *gmp_args],
|
||||
download_url="https://ftp.gnu.org/gnu/gmp/",
|
||||
download_name=f"gmp-{GMP_VERSION}.tar.bz2"
|
||||
)
|
||||
@@ -645,7 +718,7 @@ if "cgal" in targets:
|
||||
build_dependency(
|
||||
name=f"mpfr-{MPFR_VERSION}",
|
||||
mode="autoconf",
|
||||
build_tool_args=[ENABLE_FLAG, DISABLE_FLAG, f"--with-gmp={DEPS_DIR}/install/gmp-{GMP_VERSION}"],
|
||||
build_tool_args=[ENABLE_FLAG, DISABLE_FLAG, *mpfr_args, f"--with-gmp={DEPS_DIR}/install/gmp-{GMP_VERSION}"],
|
||||
download_url=f"http://www.mpfr.org/mpfr-{MPFR_VERSION}/",
|
||||
download_name=f"mpfr-{MPFR_VERSION}.tar.bz2"
|
||||
)
|
||||
@@ -679,18 +752,8 @@ os.makedirs(IFCOS_DIR, exist_ok=True)
|
||||
executables_dir = os.path.join(IFCOS_DIR, "executables")
|
||||
os.makedirs(executables_dir, exist_ok=True)
|
||||
|
||||
logger.info("\rConfiguring executables...")
|
||||
|
||||
OFF_ON = ["OFF", "ON"]
|
||||
|
||||
exec_args = [
|
||||
"-DBUILD_IFCGEOM=" +OFF_ON["IfcGeom" in targets],
|
||||
"-DBUILD_GEOMSERVER=" +OFF_ON["IfcGeomServer" in targets],
|
||||
"-DBUILD_CONVERT=" +OFF_ON["IfcConvert" in targets],
|
||||
"-DBUILD_IFCPYTHON=" "OFF",
|
||||
"-DCMAKE_INSTALL_PREFIX=" f"{DEPS_DIR}/install/ifcopenshell",
|
||||
]
|
||||
|
||||
cmake_args = [
|
||||
"-DUSE_MMAP=" "OFF",
|
||||
"-DBUILD_EXAMPLES=" "OFF",
|
||||
@@ -702,6 +765,11 @@ cmake_args = [
|
||||
"-DADD_COMMIT_SHA=" +("On" if ADD_COMMIT_SHA else "Off")
|
||||
]
|
||||
|
||||
if "wasm" in flags:
|
||||
# Boost is built by the build script so should not be found
|
||||
# inside of the sysroot set by the emscriptem toolchain
|
||||
cmake_args.append("-DWASM_BUILD=On")
|
||||
|
||||
if "cgal" in targets:
|
||||
cmake_args.extend([
|
||||
"-DCGAL_INCLUDE_DIR=" f"{DEPS_DIR}/install/cgal-{CGAL_VERSION}/include",
|
||||
@@ -753,20 +821,36 @@ if "hdf5" in targets:
|
||||
"-DHDF5_INCLUDE_DIR=" f"{DEPS_DIR}/install/hdf5-{HDF5_VERSION}/include",
|
||||
"-DHDF5_LIBRARY_DIR=" f"{DEPS_DIR}/install/hdf5-{HDF5_VERSION}/lib"
|
||||
])
|
||||
else:
|
||||
cmake_args.append("-DHDF5_SUPPORT=Off")
|
||||
|
||||
run_cmake("", exec_args + cmake_args, cmake_dir=CMAKE_DIR, cwd=executables_dir)
|
||||
if not explicit_targets or {"IfcGeom", "IfcConvert", "IfcGeomServer"} & set(explicit_targets):
|
||||
logger.info("\rConfiguring executables...")
|
||||
|
||||
logger.info("\rBuilding executables... ")
|
||||
exec_args = [
|
||||
"-DBUILD_IFCGEOM=" +OFF_ON["IfcGeom" in targets],
|
||||
"-DBUILD_GEOMSERVER=" +OFF_ON["IfcGeomServer" in targets],
|
||||
"-DBUILD_CONVERT=" +OFF_ON["IfcConvert" in targets],
|
||||
"-DBUILD_IFCPYTHON=" "OFF",
|
||||
"-DCMAKE_INSTALL_PREFIX=" f"{DEPS_DIR}/install/ifcopenshell",
|
||||
]
|
||||
|
||||
run_cmake("", exec_args + cmake_args, cmake_dir=CMAKE_DIR, cwd=executables_dir)
|
||||
|
||||
run([make, f"-j{IFCOS_NUM_BUILD_PROCS}"], cwd=executables_dir)
|
||||
run([make, "install/strip" if BUILD_CFG == "Release" else "install"], cwd=executables_dir)
|
||||
logger.info("\rBuilding executables... ")
|
||||
|
||||
run([make, f"-j{IFCOS_NUM_BUILD_PROCS}"], cwd=executables_dir)
|
||||
run([make, "install/strip" if BUILD_CFG == "Release" else "install"], cwd=executables_dir)
|
||||
|
||||
if "IfcOpenShell-Python" in targets:
|
||||
# On OSX the actual Python library is not linked against.
|
||||
ADDITIONAL_ARGS = ""
|
||||
if platform.system() == "Darwin":
|
||||
ADDITIONAL_ARGS = "-Wl,-flat_namespace,-undefined,suppress"
|
||||
|
||||
|
||||
if "wasm" in flags:
|
||||
ADDITIONAL_ARGS = f"-Wl,-undefined,suppress -sSIDE_MODULE=2 -sEXPORTED_FUNCTIONS=_PyInit__ifcopenshell_wrapper"
|
||||
|
||||
os.environ["CXXFLAGS"] = f"{CXXFLAGS_MINIMAL} {ADDITIONAL_ARGS}"
|
||||
os.environ["CFLAGS"] = f"{CFLAGS_MINIMAL} {ADDITIONAL_ARGS}"
|
||||
os.environ["LDFLAGS"] = f"{LDFLAGS} {ADDITIONAL_ARGS}"
|
||||
@@ -783,36 +867,57 @@ if "IfcOpenShell-Python" in targets:
|
||||
|
||||
os.environ["PYTHON_LIBRARY_BASENAME"] = os.path.basename(python_library)
|
||||
|
||||
swig_when_built = []
|
||||
if "swig" in targets:
|
||||
swig_when_built.append(f"-DSWIG_EXECUTABLE={DEPS_DIR}/install/swig/bin/swig")
|
||||
|
||||
run_cmake("",
|
||||
cmake_args + [
|
||||
"-DPYTHON_LIBRARY=" +python_library,
|
||||
"-DPYTHON_EXECUTABLE=" +python_executable,
|
||||
*([f"-DPYTHON_EXECUTABLE={python_executable}"] if python_executable else []),
|
||||
# *([f"-DPYTHON_MODULE_INSTALL_DIR={os.environ['PYTHONPATH']}/ifcopenshell"] if "wasm" in flags else []),
|
||||
*(["-DPYTHON_MODULE_INSTALL_DIR="+os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "package"))] if "wasm" in flags else []),
|
||||
"-DPYTHON_INCLUDE_DIR=" +python_include,
|
||||
"-DSWIG_EXECUTABLE=" f"{DEPS_DIR}/install/swig/bin/swig",
|
||||
"-DCMAKE_INSTALL_PREFIX=" f"{DEPS_DIR}/install/ifcopenshell/tmp",
|
||||
"-DUSERSPACE_PYTHON_PREFIX=" +["Off", "On"][os.environ.get("PYTHON_USER_SITE", "").lower() in {"1", "on", "true"}]
|
||||
], cmake_dir=CMAKE_DIR, cwd=python_dir)
|
||||
"-DUSERSPACE_PYTHON_PREFIX=" +["Off", "On"][os.environ.get("PYTHON_USER_SITE", "").lower() in {"1", "on", "true"}],
|
||||
*swig_when_built],
|
||||
cmake_dir=CMAKE_DIR, cwd=python_dir)
|
||||
|
||||
logger.info(f"\rBuilding python {python_version} wrapper... ")
|
||||
|
||||
run([make, f"-j{IFCOS_NUM_BUILD_PROCS}", "_ifcopenshell_wrapper"], cwd=python_dir)
|
||||
run([make, "install/local"], cwd=os.path.join(python_dir, "ifcwrap"))
|
||||
|
||||
module_dir = os.path.dirname(run([python_executable, "-c", "import inspect, ifcopenshell; print(inspect.getfile(ifcopenshell))"]))
|
||||
if python_executable:
|
||||
module_dir = os.path.dirname(run([python_executable, "-c", "import inspect, ifcopenshell; print(inspect.getfile(ifcopenshell))"]))
|
||||
|
||||
if platform.system() != "Darwin":
|
||||
# TODO: This symbol name depends on the Python version?
|
||||
run([strip, "-s", "-K", "PyInit__ifcopenshell_wrapper", "_ifcopenshell_wrapper.so"], cwd=module_dir)
|
||||
return module_dir
|
||||
if platform.system() != "Darwin":
|
||||
# TODO: This symbol name depends on the Python version?
|
||||
run([strip, "-s", "-K", "PyInit__ifcopenshell_wrapper", "_ifcopenshell_wrapper.so"], cwd=module_dir)
|
||||
|
||||
return module_dir
|
||||
|
||||
if USE_CURRENT_PYTHON_VERSION:
|
||||
python_info = sysconfig.get_paths()
|
||||
python_lib = os.path.join(
|
||||
sysconfig.get_config_var('LIBDIR'),
|
||||
sysconfig.get_config_var('multiarchsubdir').replace("/", ""),
|
||||
sysconfig.get_config_var("INSTSONAME")
|
||||
if "wasm" in flags:
|
||||
compile_python_wrapper(
|
||||
f"{os.environ['PYMAJOR']}.{os.environ['PYMINOR']}.{os.environ['PYMICRO']}",
|
||||
f"{os.environ['TARGETINSTALLDIR']}/lib/libpython{os.environ['PYMAJOR']}.{os.environ['PYMINOR']}.a",
|
||||
os.environ['PYTHONINCLUDE'],
|
||||
None
|
||||
)
|
||||
|
||||
elif USE_CURRENT_PYTHON_VERSION:
|
||||
python_info = sysconfig.get_paths()
|
||||
|
||||
py_path_components = [
|
||||
sysconfig.get_config_var('LIBDIR'),
|
||||
sysconfig.get_config_var("INSTSONAME")
|
||||
]
|
||||
|
||||
if sysconfig.get_config_var('multiarchsubdir'):
|
||||
py_path_components.insert(1, sysconfig.get_config_var('multiarchsubdir').replace("/", ""))
|
||||
|
||||
python_lib = os.path.join(*py_path_components)
|
||||
|
||||
compile_python_wrapper(platform.python_version(), python_lib, python_info["include"], sys.executable)
|
||||
else:
|
||||
for python_version in PYTHON_VERSIONS:
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
--- a/tools/build/src/tools/emscripten.jam
|
||||
+++ b/tools/build/src/tools/emscripten.jam
|
||||
@@ -6,6 +6,7 @@
|
||||
import feature ;
|
||||
import os ;
|
||||
import toolset ;
|
||||
+import generators ;
|
||||
import common ;
|
||||
import gcc ;
|
||||
import type ;
|
||||
@@ -52,6 +53,8 @@
|
||||
<debug-symbols>off <debug-symbols>on
|
||||
<rtti>off <rtti>on
|
||||
;
|
||||
+generators.override builtin.lib-generator : emscripten.prebuilt ;
|
||||
+generators.override emscripten.searched-lib-generator : searched-lib-generator ;
|
||||
|
||||
type.set-generated-target-suffix EXE : <toolset>emscripten : "js" ;
|
||||
type.set-generated-target-suffix OBJ : <toolset>emscripten : "bc" ;
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
diff --git a/src/Message/Message_PrinterSystemLog.cxx b/src/Message/Message_PrinterSystemLog.cxx
|
||||
index 0c82c2167..a2e9e6d68 100644
|
||||
--- a/src/Message/Message_PrinterSystemLog.cxx
|
||||
+++ b/src/Message/Message_PrinterSystemLog.cxx
|
||||
@@ -55,27 +55,6 @@
|
||||
return ANDROID_LOG_DEBUG;
|
||||
}
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
- #include <emscripten/emscripten.h>
|
||||
-
|
||||
- //! Print message to console.debug().
|
||||
- EM_JS(void, occJSConsoleDebug, (const char* theStr), {
|
||||
- console.debug(UTF8ToString(theStr));
|
||||
- });
|
||||
-
|
||||
- //! Print message to console.info().
|
||||
- EM_JS(void, occJSConsoleInfo, (const char* theStr), {
|
||||
- console.info(UTF8ToString(theStr));
|
||||
- });
|
||||
-
|
||||
- //! Print message to console.warn().
|
||||
- EM_JS(void, occJSConsoleWarn, (const char* theStr), {
|
||||
- console.warn(UTF8ToString(theStr));
|
||||
- });
|
||||
-
|
||||
- //! Print message to console.error().
|
||||
- EM_JS(void, occJSConsoleError, (const char* theStr), {
|
||||
- console.error(UTF8ToString(theStr));
|
||||
- });
|
||||
#else
|
||||
#include <syslog.h>
|
||||
|
||||
@@ -169,16 +148,6 @@ void Message_PrinterSystemLog::send (const TCollection_AsciiString& theString,
|
||||
#elif defined(__ANDROID__)
|
||||
__android_log_write (getAndroidLogPriority (theGravity), myEventSourceName.ToCString(), theString.ToCString());
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
- // don't use bogus emscripten_log() corrupting UNICODE strings
|
||||
- switch (theGravity)
|
||||
- {
|
||||
- case Message_Trace: occJSConsoleDebug(theString.ToCString()); return;
|
||||
- case Message_Info: occJSConsoleInfo (theString.ToCString()); return;
|
||||
- case Message_Warning: occJSConsoleWarn (theString.ToCString()); return;
|
||||
- case Message_Alarm: occJSConsoleError(theString.ToCString()); return;
|
||||
- case Message_Fail: occJSConsoleError(theString.ToCString()); return;
|
||||
- }
|
||||
- occJSConsoleWarn (theString.ToCString());
|
||||
#else
|
||||
syslog (getSysLogPriority (theGravity), "%s", theString.ToCString());
|
||||
#endif
|
||||
diff --git a/src/OSD/OSD_MemInfo.cxx b/src/OSD/OSD_MemInfo.cxx
|
||||
index 08a939beb..7c1fc79b3 100644
|
||||
--- a/src/OSD/OSD_MemInfo.cxx
|
||||
+++ b/src/OSD/OSD_MemInfo.cxx
|
||||
@@ -37,15 +37,6 @@
|
||||
|
||||
#include <OSD_MemInfo.hxx>
|
||||
|
||||
-#if defined(__EMSCRIPTEN__)
|
||||
- #include <emscripten.h>
|
||||
-
|
||||
- //! Return WebAssembly heap size in bytes.
|
||||
- EM_JS(size_t, OSD_MemInfo_getModuleHeapLength, (), {
|
||||
- return Module.HEAP8.length;
|
||||
- });
|
||||
-#endif
|
||||
-
|
||||
// =======================================================================
|
||||
// function : OSD_MemInfo
|
||||
// purpose :
|
||||
@@ -156,29 +147,6 @@ void OSD_MemInfo::Update()
|
||||
}
|
||||
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
- if (IsActive (MemHeapUsage)
|
||||
- || IsActive (MemWorkingSet)
|
||||
- || IsActive (MemWorkingSetPeak))
|
||||
- {
|
||||
- // /proc/%d/status is not emulated - get more info from mallinfo()
|
||||
- const struct mallinfo aMI = mallinfo();
|
||||
- if (IsActive (MemHeapUsage))
|
||||
- {
|
||||
- myCounters[MemHeapUsage] = aMI.uordblks;
|
||||
- }
|
||||
- if (IsActive (MemWorkingSet))
|
||||
- {
|
||||
- myCounters[MemWorkingSet] = aMI.uordblks;
|
||||
- }
|
||||
- if (IsActive (MemWorkingSetPeak))
|
||||
- {
|
||||
- myCounters[MemWorkingSetPeak] = aMI.usmblks;
|
||||
- }
|
||||
- }
|
||||
- if (IsActive (MemVirtual))
|
||||
- {
|
||||
- myCounters[MemVirtual] = OSD_MemInfo_getModuleHeapLength();
|
||||
- }
|
||||
#elif (defined(__linux__) || defined(__linux))
|
||||
if (IsActive (MemHeapUsage))
|
||||
{
|
||||
@@ -0,0 +1,81 @@
|
||||
diff --git a/COLLADABaseUtils/include/COLLADABUhash_map.h b/COLLADABaseUtils/include/COLLADABUhash_map.h
|
||||
index 8ab0fb9b..12503bfb 100644
|
||||
--- a/COLLADABaseUtils/include/COLLADABUhash_map.h
|
||||
+++ b/COLLADABaseUtils/include/COLLADABUhash_map.h
|
||||
@@ -32,9 +32,9 @@
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
- #define COLLADABU_HASH_MAP std::tr1::unordered_map
|
||||
- #define COLLADABU_HASH_MULTIMAP std::tr1::unordered_multimap
|
||||
- #define COLLADABU_HASH_SET std::tr1::unordered_set
|
||||
+ #define COLLADABU_HASH_MAP std::unordered_map
|
||||
+ #define COLLADABU_HASH_MULTIMAP std::unordered_multimap
|
||||
+ #define COLLADABU_HASH_SET std::unordered_set
|
||||
#define COLLADABU_HASH_NAMESPACE_OPEN std { namespace tr1
|
||||
#define COLLADABU_HASH_NAMESPACE_CLOSE }
|
||||
#define COLLADABU_HASH_FUN hash
|
||||
@@ -50,12 +50,12 @@
|
||||
#define COLLADABU_HASH_FUN hash
|
||||
#endif
|
||||
#elif defined(__MINGW32__) || defined(__MINGW64__)
|
||||
- #include <tr1/unordered_map>
|
||||
- #include <tr1/unordered_set>
|
||||
+ #include <unordered_map>
|
||||
+ #include <unordered_set>
|
||||
|
||||
- #define COLLADABU_HASH_MAP std::tr1::unordered_map
|
||||
- #define COLLADABU_HASH_MULTIMAP std::tr1::unordered_multimap
|
||||
- #define COLLADABU_HASH_SET std::tr1::unordered_set
|
||||
+ #define COLLADABU_HASH_MAP std::unordered_map
|
||||
+ #define COLLADABU_HASH_MULTIMAP std::unordered_multimap
|
||||
+ #define COLLADABU_HASH_SET std::unordered_set
|
||||
#define COLLADABU_HASH_NAMESPACE_OPEN std { namespace tr1
|
||||
#define COLLADABU_HASH_NAMESPACE_CLOSE }
|
||||
#define COLLADABU_HASH_FUN hash
|
||||
@@ -107,12 +107,12 @@
|
||||
#define COLLADABU_HASH_NAMESPACE_CLOSE
|
||||
#define COLLADABU_HASH_FUN hash
|
||||
#else
|
||||
- #include <tr1/unordered_map>
|
||||
- #include <tr1/unordered_set>
|
||||
+ #include <unordered_map>
|
||||
+ #include <unordered_set>
|
||||
|
||||
- #define COLLADABU_HASH_MAP std::tr1::unordered_map
|
||||
- #define COLLADABU_HASH_MULTIMAP std::tr1::unordered_multimap
|
||||
- #define COLLADABU_HASH_SET std::tr1::unordered_set
|
||||
+ #define COLLADABU_HASH_MAP std::unordered_map
|
||||
+ #define COLLADABU_HASH_MULTIMAP std::unordered_multimap
|
||||
+ #define COLLADABU_HASH_SET std::unordered_set
|
||||
#define COLLADABU_HASH_NAMESPACE_OPEN std { namespace tr1
|
||||
#define COLLADABU_HASH_NAMESPACE_CLOSE }
|
||||
#define COLLADABU_HASH_FUN hash
|
||||
diff --git a/common/libBuffer/include/CommonFWriteBufferFlusher.h b/common/libBuffer/include/CommonFWriteBufferFlusher.h
|
||||
index c7af45b2..fac4f133 100644
|
||||
--- a/common/libBuffer/include/CommonFWriteBufferFlusher.h
|
||||
+++ b/common/libBuffer/include/CommonFWriteBufferFlusher.h
|
||||
@@ -15,12 +15,12 @@
|
||||
|
||||
#if (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) || (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__APPLE__))
|
||||
#if defined(__GNUC__) && !defined(_LIBCPP_VERSION)
|
||||
-# include <tr1/unordered_map>
|
||||
+# include <unordered_map>
|
||||
#else
|
||||
# include <unordered_map>
|
||||
#endif
|
||||
#else
|
||||
-# include <tr1/unordered_map>
|
||||
+# include <unordered_map>
|
||||
#endif
|
||||
|
||||
#ifdef _LIBCPP_VERSION
|
||||
@@ -58,7 +58,7 @@ namespace Common
|
||||
#else
|
||||
typedef __int64 FilePosType;
|
||||
#endif
|
||||
- typedef std::tr1::unordered_map<MarkId, FilePosType > MarkIdToFilePos;
|
||||
+ typedef std::unordered_map<MarkId, FilePosType > MarkIdToFilePos;
|
||||
|
||||
public:
|
||||
static const size_t DEFAUL_BUFFER_SIZE = 64*1024;
|
||||
@@ -0,0 +1,18 @@
|
||||
package:
|
||||
name: ifcopenshell
|
||||
version: 0.7.0
|
||||
|
||||
source:
|
||||
path: IfcOpenShell
|
||||
|
||||
build:
|
||||
script: |
|
||||
python nix/build-all.py --without-hdf5 --without-opencollada --without-swig --without-pcre -v --wasm --py310 IfcOpenShell-Python
|
||||
cp pyodide/setup.py .
|
||||
|
||||
about:
|
||||
home: http://ifcopenshell.org
|
||||
license: LGPL-3.0-or-later
|
||||
summary: |
|
||||
IfcOpenShell is an open source (LGPL) software library for
|
||||
working with the Industry Foundation Classes (IFC) file format.
|
||||
@@ -0,0 +1,11 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(name='IfcOpenShell',
|
||||
version='0.7.0',
|
||||
description='IfcOpenShell is an open source (LGPL) software library for working with the Industry Foundation Classes (IFC) file format.',
|
||||
author='Thomas Krijnen',
|
||||
author_email='thomas@aecgeeks.com',
|
||||
url='http://ifcopenshell.org',
|
||||
packages=find_packages(),
|
||||
package_data={'': ['*.so']},
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
# This CITATION.cff file was generated with cffinit.
|
||||
# Visit https://bit.ly/cffinit to generate yours today!
|
||||
|
||||
cff-version: 1.2.0
|
||||
title: bcf
|
||||
message: >-
|
||||
If you use this software, please cite it using the
|
||||
metadata from this file.
|
||||
type: software
|
||||
authors:
|
||||
- name: "IfcOpenShell contributors"
|
||||
repository-code: >-
|
||||
https://github.com/IfcOpenShell/IfcOpenShell/tree/v0.7.0/src/bcf
|
||||
abstract: >-
|
||||
Library to read and write BCF-XML and query OpenCDE
|
||||
BCF-API modules
|
||||
keywords:
|
||||
- BCF
|
||||
- IFC
|
||||
license: LGPL-3.0-or-later
|
||||
@@ -1,31 +1,11 @@
|
||||
.PHONY: test
|
||||
test:
|
||||
.PHONY: ci
|
||||
ci:
|
||||
tox
|
||||
|
||||
.PHONY: qa
|
||||
qa:
|
||||
black .
|
||||
isort .
|
||||
pylint ./src --output-format=colorized
|
||||
|
||||
.PHONY: typecheck
|
||||
typecheck:
|
||||
mypy src/bcf
|
||||
|
||||
.PHONY: license
|
||||
license:
|
||||
copyright-header --license LGPL3 --copyright-holder "Andrea Ghensi <andrea.ghensi@gmail.com>" --copyright-year "2022" --copyright-software "IfcOpenShell" --copyright-software-description "BCF XML file handling" -a ./ -o ./
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
coverage run --source bcf -m pytest tests
|
||||
coverage html
|
||||
xdg-open htmlcov/index.html
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf htmlcov
|
||||
|
||||
# TODO: make this based on xsd file presence
|
||||
.PHONY: models
|
||||
models:
|
||||
|
||||
@@ -27,7 +27,7 @@ with load("/path/to/file.bcf") as bcfxml:
|
||||
# Get a dictionary of topics
|
||||
topics = bcfxml.topics
|
||||
|
||||
for topic_handler in bcfxml.topics:
|
||||
for topic_guid, topic_handler in bcfxml.topics.items():
|
||||
topic = topic_handler.topic
|
||||
print("Topic guid is", topic.guid)
|
||||
print("Topic title is", topic.title)
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
name: bcf-client
|
||||
channels:
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- ifcopenshell
|
||||
- xsdata
|
||||
- numpy
|
||||
@@ -11,10 +11,11 @@ name = "bcf-client"
|
||||
description = "BCF-XML file handler."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.8"
|
||||
keywords = ["IFC", "BCF", "BIM", "eingineering"]
|
||||
keywords = ["IFC", "BCF", "BIM"]
|
||||
dependencies = [
|
||||
"xsdata",
|
||||
"numpy",
|
||||
"ifcopenshell",
|
||||
]
|
||||
version = "0.0.1"
|
||||
classifiers = [
|
||||
@@ -58,20 +59,34 @@ exclude_lines = [
|
||||
[tool.tox]
|
||||
legacy_tox_ini = """
|
||||
[tox]
|
||||
envlist = py310
|
||||
isolated_build = true
|
||||
env_list = lint, type, py3{10,11}
|
||||
skip_missing_interpreters = true
|
||||
requires = tox-conda
|
||||
|
||||
[testenv]
|
||||
conda_deps =
|
||||
deps =
|
||||
pytest
|
||||
pytest-cov
|
||||
coverage
|
||||
conda_channels =
|
||||
conda-forge
|
||||
conda_env = environment.yml
|
||||
commands = pytest --cov --cov-report=term tests
|
||||
|
||||
[testenv:lint]
|
||||
description = run linters
|
||||
skip_install = true
|
||||
deps =
|
||||
black
|
||||
isort
|
||||
pylint
|
||||
commands =
|
||||
black {posargs:.}
|
||||
isort {posargs:.}
|
||||
pylint {posargs:.} --output-format=colorized
|
||||
|
||||
[testenv:type]
|
||||
description = run type checks
|
||||
deps =
|
||||
mypy>=0.991
|
||||
commands =
|
||||
- mypy {posargs:src}
|
||||
"""
|
||||
|
||||
[tool.mypy]
|
||||
|
||||
@@ -3,5 +3,4 @@ mypy
|
||||
pylint
|
||||
isort
|
||||
xsdata
|
||||
tox
|
||||
tox-conda
|
||||
tox==3.27.1
|
||||
|
||||
@@ -23,8 +23,9 @@ from pathlib import Path
|
||||
from typing import Optional, Union
|
||||
|
||||
from bcf.v2.bcfxml import BcfXml as BcfXml2
|
||||
from bcf.v2.model import Version as Version2
|
||||
from bcf.v3.bcfxml import BcfXml as BcfXml3
|
||||
from bcf.v3.model import Version
|
||||
from bcf.v3.model import Version as Version3
|
||||
from bcf.xml_parser import AbstractXmlParserSerializer, XmlParserSerializer
|
||||
|
||||
|
||||
@@ -65,5 +66,8 @@ def _get_version(filepath: Union[str, Path], xml_handler: Optional[AbstractXmlPa
|
||||
"""
|
||||
xml_handler = xml_handler or XmlParserSerializer()
|
||||
with zipfile.ZipFile(filepath) as bcf_zip:
|
||||
version = xml_handler.parse(bcf_zip.read("bcf.version"), Version)
|
||||
try:
|
||||
version = xml_handler.parse(bcf_zip.read("bcf.version"), Version3)
|
||||
except:
|
||||
version = xml_handler.parse(bcf_zip.read("bcf.version"), Version2)
|
||||
return version.version_id
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from typing import Optional
|
||||
|
||||
import numpy as np
|
||||
from numpy.typing import NDArray
|
||||
|
||||
|
||||
def calc_camera_vectors(
|
||||
def camera_vectors_from_element_placement(
|
||||
elem_placement: NDArray[np.float_],
|
||||
) -> tuple[NDArray[np.float_], NDArray[np.float_], NDArray[np.float_]]:
|
||||
"""
|
||||
@@ -15,19 +17,37 @@ def calc_camera_vectors(
|
||||
Camera position, direction and up vectors
|
||||
"""
|
||||
target_position = elem_placement[:3, 3]
|
||||
camera_position = target_position + np.array((5, 5, 5))
|
||||
camera_direction = unit_vector(camera_position - target_position)
|
||||
return camera_vectors_from_target_position(target_position)
|
||||
|
||||
|
||||
def camera_vectors_from_target_position(
|
||||
target_position: NDArray[np.float_], offset: Optional[NDArray[np.float_]] = None
|
||||
) -> tuple[NDArray[np.float_], NDArray[np.float_], NDArray[np.float_]]:
|
||||
"""
|
||||
Calculate the vectors of a camera pointing to a target point.
|
||||
|
||||
Args:
|
||||
target_position: point the camera is pointing to.
|
||||
camera_offset: offset of the camera from the target point.
|
||||
|
||||
Returns:
|
||||
Camera position, direction and up vectors
|
||||
"""
|
||||
camera_offset = np.array((5, 5, 5)) if offset is None else offset
|
||||
camera_position = target_position + camera_offset
|
||||
camera_direction = unit_vector(-camera_offset) # pylint: disable=invalid-unary-operand-type
|
||||
camera_right = unit_vector(np.cross(np.array([0.0, 0.0, 1.0]), camera_direction))
|
||||
camera_up = unit_vector(np.cross(camera_direction, camera_right))
|
||||
rotation_transform = np.eye(4)
|
||||
rotation_transform[0, :3] = camera_right
|
||||
rotation_transform[1, :3] = camera_up
|
||||
rotation_transform[2, :3] = camera_direction
|
||||
translation_transform = np.eye(4)
|
||||
translation_transform[:3, -1] = -camera_position
|
||||
look_at_transform = np.matmul(rotation_transform, translation_transform)
|
||||
mat = np.linalg.inv(look_at_transform)
|
||||
return camera_position, -mat[:3, 2], mat[:3, 1]
|
||||
return camera_position, camera_direction, camera_up
|
||||
# rotation_transform = np.eye(4)
|
||||
# rotation_transform[0, :3] = camera_right
|
||||
# rotation_transform[1, :3] = camera_up
|
||||
# rotation_transform[2, :3] = camera_direction
|
||||
# translation_transform = np.eye(4)
|
||||
# translation_transform[:3, -1] = -camera_position
|
||||
# look_at_transform = np.matmul(rotation_transform, translation_transform)
|
||||
# mat = np.linalg.inv(look_at_transform)
|
||||
# return camera_position, -mat[:3, 2], mat[:3, 1]
|
||||
|
||||
|
||||
def unit_vector(v: NDArray[np.float_]) -> NDArray[np.float_]:
|
||||
|
||||
@@ -3,7 +3,7 @@ import uuid
|
||||
import warnings
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional, TypeVar
|
||||
from typing import Any, NoReturn, Optional, TypeVar
|
||||
|
||||
import bcf.v2.model as mdl
|
||||
from bcf.inmemory_zipfile import InMemoryZipFile, ZipFileInterface
|
||||
@@ -50,7 +50,7 @@ class BcfXml:
|
||||
self._version = (
|
||||
self._xml_handler.parse(self._zip_file.read("bcf.version"), mdl.Version)
|
||||
if self._zip_file
|
||||
else mdl.Version(version_id="3.0")
|
||||
else mdl.Version(version_id="2.1")
|
||||
)
|
||||
return self._version
|
||||
|
||||
@@ -210,10 +210,12 @@ class BcfXml:
|
||||
self.topics[topic_handler.guid] = topic_handler
|
||||
return topic_handler
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, BcfXml):
|
||||
raise TypeError("Equality needs a BcfXml object.")
|
||||
return self.version == other.version and self.project_info == other.project_info
|
||||
def __eq__(self, other: object) -> bool | NoReturn:
|
||||
return (
|
||||
self.version == other.version and self.project_info == other.project_info
|
||||
if isinstance(other, BcfXml)
|
||||
else NotImplemented
|
||||
)
|
||||
|
||||
# region Deprecated methods
|
||||
def new_project(self) -> "BcfXml":
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
"""BCF XML V2 Topic handler."""
|
||||
import datetime
|
||||
import tempfile
|
||||
import uuid
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
from typing import Any, NoReturn, Optional
|
||||
|
||||
import numpy as np
|
||||
from ifcopenshell import entity_instance
|
||||
from numpy.typing import NDArray
|
||||
from xsdata.models.datatype import XmlDateTime
|
||||
|
||||
import bcf.v2.model as mdl
|
||||
@@ -216,25 +219,88 @@ class TopicHandler:
|
||||
real_path = real_path.parent if path_part == ".." else real_path.joinpath(path_part)
|
||||
destination_zip.writestr(real_path.at, self.document_references[doc.referenced_document])
|
||||
|
||||
def add_viewpoint(self, element: entity_instance) -> None:
|
||||
def extract_file(self, entity, outfile: Optional[Path] = None) -> Path:
|
||||
"""Extracts an element with a file into a temporary directory
|
||||
|
||||
These include header files, bim snippets, document references, and
|
||||
viewpoint bitmaps. External reference are not downloaded. Instead, the
|
||||
URI reference is returned.
|
||||
|
||||
:param entity: The entity with a file reference to extract
|
||||
:type entity: bcf.v2.model.HeaderFile,bcf.v2.model.BimSnippet,bcf.v2.model.TopicDocumentReference
|
||||
:param outfile: If provided, save the header file to that location.
|
||||
Otherwise, a temporary directory is created and the filename is
|
||||
derived from the header's original filename.
|
||||
:type outfile: pathlib.Path,optional
|
||||
:return: The filepath of the extracted file. It may be a URL if the
|
||||
header file is external.
|
||||
:rtype: Path
|
||||
"""
|
||||
Add a viewpoint tergeting an IFC element to the topic.
|
||||
if hasattr(entity, "reference"):
|
||||
reference = entity.reference
|
||||
else:
|
||||
reference = entity.referenced_document
|
||||
|
||||
if not reference:
|
||||
return
|
||||
|
||||
if getattr(entity, "is_external", False):
|
||||
return entity.reference
|
||||
|
||||
resolved_reference = self._topic_dir
|
||||
|
||||
for part in Path(reference).parts:
|
||||
if part == "..":
|
||||
resolved_reference = resolved_reference.parent
|
||||
else:
|
||||
resolved_reference = resolved_reference.joinpath(part)
|
||||
|
||||
if not outfile:
|
||||
if getattr(entity, "filename", None):
|
||||
filename = entity.filename
|
||||
else:
|
||||
filename = resolved_reference.name
|
||||
outfile = Path(tempfile.mkdtemp()) / filename
|
||||
|
||||
with open(outfile, "wb") as f:
|
||||
f.write(resolved_reference.read_bytes())
|
||||
|
||||
return outfile
|
||||
|
||||
def add_viewpoint(self, element: entity_instance) -> None:
|
||||
"""Add a viewpoint pointed at the placement of an IFC element to the topic.
|
||||
|
||||
Args:
|
||||
element: The IFC element.
|
||||
"""
|
||||
new_viewpoint = VisualizationInfoHandler.create_new(element, self._xml_handler)
|
||||
self.add_visinfo_handler(new_viewpoint)
|
||||
return new_viewpoint
|
||||
|
||||
def add_viewpoint_from_point_and_guids(self, position: NDArray[np.float_], *guids: str) -> None:
|
||||
"""Add a viewpoint pointing at an XYZ point in space
|
||||
|
||||
Args:
|
||||
position: the XYZ point in space
|
||||
guids: one or more element GlobalIds.
|
||||
"""
|
||||
vi_handler = VisualizationInfoHandler.create_from_point_and_guids(
|
||||
position, *guids, xml_handler=self._xml_handler
|
||||
)
|
||||
self.add_visinfo_handler(vi_handler)
|
||||
return vi_handler
|
||||
|
||||
def add_visinfo_handler(self, new_viewpoint: VisualizationInfoHandler) -> None:
|
||||
self.viewpoints[new_viewpoint.guid] = new_viewpoint
|
||||
self.markup.viewpoints.append(mdl.ViewPoint(viewpoint=new_viewpoint.guid, guid=new_viewpoint.guid))
|
||||
self.viewpoints[new_viewpoint.guid + ".bcfv"] = new_viewpoint
|
||||
self.markup.viewpoints.append(mdl.ViewPoint(viewpoint=new_viewpoint.guid + ".bcfv", guid=new_viewpoint.guid))
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, TopicHandler):
|
||||
raise TypeError("Equality needs a BcfXml object.")
|
||||
def __eq__(self, other: object) -> bool | NoReturn:
|
||||
return (
|
||||
self.markup == other.markup
|
||||
and self.viewpoints == other.viewpoints
|
||||
and self.bim_snippet == other.bim_snippet
|
||||
(
|
||||
self.markup == other.markup
|
||||
and self.viewpoints == other.viewpoints
|
||||
and self.bim_snippet == other.bim_snippet
|
||||
)
|
||||
if isinstance(other, TopicHandler)
|
||||
else NotImplemented
|
||||
)
|
||||
|
||||
@@ -5,11 +5,15 @@ from typing import Any, Iterable, Optional
|
||||
|
||||
import numpy as np
|
||||
from ifcopenshell import entity_instance
|
||||
from ifcopenshell.util import placement
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.placement
|
||||
from numpy.typing import NDArray
|
||||
|
||||
import bcf.v2.model as mdl
|
||||
from bcf.geometry import calc_camera_vectors
|
||||
from bcf.geometry import (
|
||||
camera_vectors_from_element_placement,
|
||||
camera_vectors_from_target_position,
|
||||
)
|
||||
from bcf.inmemory_zipfile import ZipFileInterface
|
||||
from bcf.xml_parser import AbstractXmlParserSerializer, XmlParserSerializer
|
||||
|
||||
@@ -169,6 +173,29 @@ class VisualizationInfoHandler:
|
||||
xml_handler = xml_handler or XmlParserSerializer()
|
||||
return cls(visualization_info=build_viewpoint(element), xml_handler=xml_handler)
|
||||
|
||||
@classmethod
|
||||
def create_from_point_and_guids(
|
||||
cls,
|
||||
position: NDArray[np.float_],
|
||||
*guids: str,
|
||||
xml_handler: Optional[AbstractXmlParserSerializer] = None,
|
||||
) -> "VisualizationInfoHandler":
|
||||
"""
|
||||
Create a new VisualizationInfoHandler object from an IFC element.
|
||||
|
||||
Args:
|
||||
position: target point coordinates.
|
||||
*guids: One or more IFC element GUID.
|
||||
xml_handler: The XML handler to use.
|
||||
|
||||
Returns:
|
||||
The VisualizationInfoHandler object.
|
||||
"""
|
||||
xml_handler = xml_handler or XmlParserSerializer()
|
||||
return cls(
|
||||
visualization_info=build_viewpoint_from_position_and_guids(position, *guids), xml_handler=xml_handler
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def build_viewpoint(element: entity_instance) -> mdl.VisualizationInfo:
|
||||
@@ -183,7 +210,12 @@ def build_viewpoint(element: entity_instance) -> mdl.VisualizationInfo:
|
||||
Returns:
|
||||
The BCF viewpoint definition.
|
||||
"""
|
||||
elem_placement = placement.get_local_placement(element.ObjectPlacement)
|
||||
ifc_file = element.wrapped_data.file
|
||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
|
||||
elem_placement = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
||||
elem_placement[0][3] *= unit_scale
|
||||
elem_placement[1][3] *= unit_scale
|
||||
elem_placement[2][3] *= unit_scale
|
||||
|
||||
return mdl.VisualizationInfo(
|
||||
guid=str(uuid.uuid4()),
|
||||
@@ -192,18 +224,39 @@ def build_viewpoint(element: entity_instance) -> mdl.VisualizationInfo:
|
||||
)
|
||||
|
||||
|
||||
def build_components(guid: str) -> mdl.Components:
|
||||
def build_viewpoint_from_position_and_guids(position: NDArray[np.float_], *guids: str) -> mdl.VisualizationInfo:
|
||||
"""
|
||||
Return a BCF viewpoint of an IFC element.
|
||||
|
||||
This function is cached to speedudp the creation of multiple BCF topics regarding the same element.
|
||||
|
||||
Args:
|
||||
position: target point coordinates.
|
||||
*guids: One or more IFC element GUID.
|
||||
|
||||
Returns:
|
||||
The BCF viewpoint definition.
|
||||
"""
|
||||
return mdl.VisualizationInfo(
|
||||
guid=str(uuid.uuid4()),
|
||||
components=build_components(*guids),
|
||||
perspective_camera=build_camera_from_vectors(*camera_vectors_from_target_position(position)),
|
||||
)
|
||||
|
||||
|
||||
def build_components(*guids: str) -> mdl.Components:
|
||||
"""
|
||||
Return the BCF components from an IFC element GUID.
|
||||
|
||||
Args:
|
||||
guid: The IFC element GUID.
|
||||
*guids: One or more IFC element GUID.
|
||||
|
||||
Returns:
|
||||
The BCF components definition.
|
||||
"""
|
||||
components = [mdl.Component(ifc_guid=guid) for guid in guids]
|
||||
return mdl.Components(
|
||||
selection=mdl.ComponentSelection(component=[mdl.Component(ifc_guid=guid)]),
|
||||
selection=mdl.ComponentSelection(component=components),
|
||||
visibility=mdl.ComponentVisibility(default_visibility=True),
|
||||
)
|
||||
|
||||
@@ -218,7 +271,7 @@ def build_camera(elem_placement: NDArray[np.float_]) -> mdl.PerspectiveCamera:
|
||||
Returns:
|
||||
The BCF camera definition.
|
||||
"""
|
||||
return build_camera_from_vectors(*calc_camera_vectors(elem_placement))
|
||||
return build_camera_from_vectors(*camera_vectors_from_element_placement(elem_placement))
|
||||
|
||||
|
||||
def build_camera_from_vectors(
|
||||
|
||||
@@ -3,7 +3,7 @@ import uuid
|
||||
import warnings
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional, TypeVar
|
||||
from typing import Any, NoReturn, Optional, TypeVar
|
||||
|
||||
import bcf.v3.model as mdl
|
||||
from bcf.inmemory_zipfile import InMemoryZipFile, ZipFileInterface
|
||||
@@ -224,13 +224,13 @@ class BcfXml:
|
||||
self.topics[topic_handler.guid] = topic_handler
|
||||
return topic_handler
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, BcfXml):
|
||||
raise TypeError("Equality needs a BcfXml object.")
|
||||
def __eq__(self, other: object) -> bool | NoReturn:
|
||||
return (
|
||||
self.version == other.version
|
||||
and self.project_info == other.project_info
|
||||
and self.extensions == other.extensions
|
||||
if isinstance(other, BcfXml)
|
||||
else NotImplemented
|
||||
)
|
||||
|
||||
# region Deprecated methods
|
||||
|
||||
@@ -3,9 +3,11 @@ import datetime
|
||||
import uuid
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
from typing import Any, NoReturn, Optional
|
||||
|
||||
import numpy as np
|
||||
from ifcopenshell import entity_instance
|
||||
from numpy.typing import NDArray
|
||||
from xsdata.models.datatype import XmlDateTime
|
||||
|
||||
import bcf.v3.model as mdl
|
||||
@@ -73,7 +75,7 @@ class TopicHandler:
|
||||
self._bim_snippet = value
|
||||
|
||||
@property
|
||||
def viewpoints(self) -> Optional[VisualizationInfoHandler]:
|
||||
def viewpoints(self) -> dict[str, "VisualizationInfoHandler"]:
|
||||
if (
|
||||
not self._viewpoints
|
||||
and self._topic_dir
|
||||
@@ -143,7 +145,7 @@ class TopicHandler:
|
||||
self._save_viewpoints(destination_zip, topic_dir)
|
||||
self._save_bim_snippet(destination_zip)
|
||||
|
||||
def _save_viewpoints(self, destination_zip, topic_dir) -> None:
|
||||
def _save_viewpoints(self, destination_zip: ZipFileInterface, topic_dir: str) -> None:
|
||||
if not self.topic.viewpoints or not (viewpoints := self.topic.viewpoints.view_point):
|
||||
return
|
||||
for vpt in viewpoints:
|
||||
@@ -172,17 +174,33 @@ class TopicHandler:
|
||||
new_viewpoint = VisualizationInfoHandler.create_new(element, self._xml_handler)
|
||||
self.add_visinfo_handler(new_viewpoint)
|
||||
|
||||
def add_viewpoint_from_point_and_guids(self, position: NDArray[np.float_], *guids: str) -> None:
|
||||
"""
|
||||
Add a viewpoint tergeting an IFC element to the topic.
|
||||
|
||||
Args:
|
||||
element: The IFC element.
|
||||
"""
|
||||
vi_handler = VisualizationInfoHandler.create_from_point_and_guids(
|
||||
position, *guids, xml_handler=self._xml_handler
|
||||
)
|
||||
self.add_visinfo_handler(vi_handler)
|
||||
|
||||
def add_visinfo_handler(self, new_viewpoint: VisualizationInfoHandler) -> None:
|
||||
self.viewpoints[new_viewpoint.guid] = new_viewpoint
|
||||
self.viewpoints[new_viewpoint.guid + ".bcfv"] = new_viewpoint
|
||||
if self.topic.viewpoints is None:
|
||||
self.topic.viewpoints = mdl.TopicViewpoints()
|
||||
self.topic.viewpoints.view_point.append(mdl.ViewPoint(viewpoint=new_viewpoint.guid, guid=new_viewpoint.guid))
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, TopicHandler):
|
||||
raise TypeError("Equality needs a BcfXml object.")
|
||||
return (
|
||||
self.markup == other.markup
|
||||
and self.viewpoints == other.viewpoints
|
||||
and self.bim_snippet == other.bim_snippet
|
||||
self.topic.viewpoints.view_point.append(
|
||||
mdl.ViewPoint(viewpoint=new_viewpoint.guid + ".bcfv", guid=new_viewpoint.guid)
|
||||
)
|
||||
|
||||
def __eq__(self, other: object) -> bool | NoReturn:
|
||||
return (
|
||||
(
|
||||
self.markup == other.markup
|
||||
and self.viewpoints == other.viewpoints
|
||||
and self.bim_snippet == other.bim_snippet
|
||||
)
|
||||
if isinstance(other, TopicHandler)
|
||||
else NotImplemented
|
||||
)
|
||||
|
||||
@@ -9,7 +9,10 @@ from ifcopenshell.util import placement
|
||||
from numpy.typing import NDArray
|
||||
|
||||
import bcf.v3.model as mdl
|
||||
from bcf.geometry import calc_camera_vectors
|
||||
from bcf.geometry import (
|
||||
camera_vectors_from_element_placement,
|
||||
camera_vectors_from_target_position,
|
||||
)
|
||||
from bcf.inmemory_zipfile import ZipFileInterface
|
||||
from bcf.xml_parser import AbstractXmlParserSerializer, XmlParserSerializer
|
||||
|
||||
@@ -169,6 +172,29 @@ class VisualizationInfoHandler:
|
||||
xml_handler = xml_handler or XmlParserSerializer()
|
||||
return cls(visualization_info=build_viewpoint(element), xml_handler=xml_handler)
|
||||
|
||||
@classmethod
|
||||
def create_from_point_and_guids(
|
||||
cls,
|
||||
position: NDArray[np.float_],
|
||||
*guids: str,
|
||||
xml_handler: Optional[AbstractXmlParserSerializer] = None,
|
||||
) -> "VisualizationInfoHandler":
|
||||
"""
|
||||
Create a new VisualizationInfoHandler object from an IFC element.
|
||||
|
||||
Args:
|
||||
position: target point coordinates.
|
||||
*guids: One or more IFC element GUID.
|
||||
xml_handler: The XML handler to use.
|
||||
|
||||
Returns:
|
||||
The VisualizationInfoHandler object.
|
||||
"""
|
||||
xml_handler = xml_handler or XmlParserSerializer()
|
||||
return cls(
|
||||
visualization_info=build_viewpoint_from_position_and_guids(position, *guids), xml_handler=xml_handler
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def build_viewpoint(element: entity_instance) -> mdl.VisualizationInfo:
|
||||
@@ -192,18 +218,39 @@ def build_viewpoint(element: entity_instance) -> mdl.VisualizationInfo:
|
||||
)
|
||||
|
||||
|
||||
def build_components(guid: str) -> mdl.Components:
|
||||
def build_viewpoint_from_position_and_guids(position: NDArray[np.float_], *guids: str) -> mdl.VisualizationInfo:
|
||||
"""
|
||||
Return a BCF viewpoint of an IFC element.
|
||||
|
||||
This function is cached to speedudp the creation of multiple BCF topics regarding the same element.
|
||||
|
||||
Args:
|
||||
position: target point coordinates.
|
||||
*guids: One or more IFC element GUID.
|
||||
|
||||
Returns:
|
||||
The BCF viewpoint definition.
|
||||
"""
|
||||
return mdl.VisualizationInfo(
|
||||
guid=str(uuid.uuid4()),
|
||||
components=build_components(*guids),
|
||||
perspective_camera=build_camera_from_vectors(*camera_vectors_from_target_position(position)),
|
||||
)
|
||||
|
||||
|
||||
def build_components(*guids: str) -> mdl.Components:
|
||||
"""
|
||||
Return the BCF components from an IFC element GUID.
|
||||
|
||||
Args:
|
||||
guid: The IFC element GUID.
|
||||
*guids: One or more IFC element GUID.
|
||||
|
||||
Returns:
|
||||
The BCF components definition.
|
||||
"""
|
||||
components = [mdl.Component(ifc_guid=guid) for guid in guids]
|
||||
return mdl.Components(
|
||||
selection=mdl.ComponentSelection(component=[mdl.Component(ifc_guid=guid)]),
|
||||
selection=mdl.ComponentSelection(component=components),
|
||||
visibility=mdl.ComponentVisibility(default_visibility=True),
|
||||
)
|
||||
|
||||
@@ -218,7 +265,7 @@ def build_camera(elem_placement: NDArray[np.float_]) -> mdl.PerspectiveCamera:
|
||||
Returns:
|
||||
The BCF camera definition.
|
||||
"""
|
||||
return build_camera_from_vectors(*calc_camera_vectors(elem_placement))
|
||||
return build_camera_from_vectors(*camera_vectors_from_element_placement(elem_placement))
|
||||
|
||||
|
||||
def build_camera_from_vectors(
|
||||
|
||||
@@ -47,12 +47,16 @@ def test_bcf_edit_saveas(xml_handler, build_sample) -> None:
|
||||
modified_path = Path(tmp_dir) / "edited.bcf"
|
||||
parsed.save(modified_path)
|
||||
with BcfXml.load(modified_path, xml_handler=xml_handler) as modified_parsed:
|
||||
assert modified_parsed == bcf
|
||||
parsed_th = modified_parsed.topics[orig_th.guid]
|
||||
assert parsed_th.markup != orig_th.markup
|
||||
assert parsed_th.markup == parsed.topics[orig_th.guid].markup
|
||||
assert parsed_th.viewpoints == orig_th.viewpoints
|
||||
assert parsed_th.bim_snippet == orig_th.bim_snippet
|
||||
_assert_modified_parsed(modified_parsed, bcf, orig_th, parsed)
|
||||
|
||||
|
||||
def _assert_modified_parsed(modified_parsed, bcf, orig_th, parsed):
|
||||
assert modified_parsed == bcf
|
||||
parsed_th = modified_parsed.topics[orig_th.guid]
|
||||
assert parsed_th.markup != orig_th.markup
|
||||
assert parsed_th.markup == parsed.topics[orig_th.guid].markup
|
||||
assert parsed_th.viewpoints == orig_th.viewpoints
|
||||
assert parsed_th.bim_snippet == orig_th.bim_snippet
|
||||
|
||||
|
||||
def test_bcf_edit(xml_handler, build_sample) -> None:
|
||||
@@ -66,13 +70,8 @@ def test_bcf_edit(xml_handler, build_sample) -> None:
|
||||
th.topic.title = "New Topic Title"
|
||||
parsed.save()
|
||||
with BcfXml.load(file_path, xml_handler=xml_handler) as modified_parsed:
|
||||
assert modified_parsed == bcf
|
||||
_assert_modified_parsed(modified_parsed, bcf, orig_th, parsed)
|
||||
assert len(modified_parsed.topics) == 1
|
||||
parsed_th = modified_parsed.topics[orig_th.guid]
|
||||
assert parsed_th.markup != orig_th.markup
|
||||
assert parsed_th.markup == parsed.topics[orig_th.guid].markup
|
||||
assert parsed_th.viewpoints == orig_th.viewpoints
|
||||
assert parsed_th.bim_snippet == orig_th.bim_snippet
|
||||
|
||||
|
||||
def test_save_no_filename(build_sample) -> None:
|
||||
@@ -112,11 +111,16 @@ def test_massive_bcf(xml_handler) -> None:
|
||||
bcf.save(file_path)
|
||||
|
||||
|
||||
def test_equality_with_wrong_object() -> None:
|
||||
with pytest.raises(TypeError):
|
||||
build_sample[0] == "Wrong object"
|
||||
def test_equality_with_wrong_object(build_sample) -> None:
|
||||
assert build_sample[0] != "Wrong object"
|
||||
|
||||
|
||||
def test_topic_equality_with_wrong_object() -> None:
|
||||
with pytest.raises(TypeError):
|
||||
build_sample[1] == "Wrong object"
|
||||
def test_topic_equality_with_wrong_object(build_sample) -> None:
|
||||
assert build_sample[1] != "Wrong object"
|
||||
|
||||
|
||||
def test_bcf_get_set_version(build_sample) -> None:
|
||||
bcf = build_sample[0]
|
||||
assert bcf.version.version_id == "2.1"
|
||||
bcf.version.version_id = "2.0"
|
||||
assert bcf.version.version_id == "2.0"
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from bcf.v2.bcfxml import BcfXml
|
||||
|
||||
|
||||
def test_create_clash_set_bcf() -> None:
|
||||
bcfxml = BcfXml.create_new("Clash Test")
|
||||
topic = bcfxml.add_topic("Test", "Test topic", "IfcClash")
|
||||
topic.add_viewpoint_from_point_and_guids(
|
||||
np.array([10, 10, 10]),
|
||||
"firstId",
|
||||
"secondId",
|
||||
)
|
||||
assert len(topic.viewpoints) == 1
|
||||
guid, vi_handler = next((k, v) for k, v in topic.viewpoints.items())
|
||||
v_info = vi_handler.visualization_info
|
||||
assert f"{v_info.guid}.bcfv" == guid
|
||||
components = v_info.components.selection.component
|
||||
assert {c.ifc_guid for c in components} == {"firstId", "secondId"}
|
||||
camera = v_info.perspective_camera
|
||||
viewpoint = camera.camera_view_point
|
||||
assert viewpoint.x == 15
|
||||
assert viewpoint.y == 15
|
||||
assert viewpoint.z == 15
|
||||
# default direction is the unit vector of -1, -1, -1
|
||||
direction = camera.camera_direction
|
||||
assert direction.x == pytest.approx(-1 / 3**0.5)
|
||||
assert direction.y == pytest.approx(-1 / 3**0.5)
|
||||
assert direction.z == pytest.approx(-1 / 3**0.5)
|
||||
# default
|
||||
up_vector = camera.camera_up_vector
|
||||
assert up_vector.x == pytest.approx(-1 / 6**0.5)
|
||||
assert up_vector.y == pytest.approx(-1 / 6**0.5)
|
||||
assert up_vector.z == pytest.approx(1 / 1.5**0.5)
|
||||
assert camera.field_of_view == 60
|
||||
@@ -48,12 +48,16 @@ def test_bcf_edit_saveas(xml_handler, build_sample) -> None:
|
||||
modified_path = Path(tmp_dir) / "edited.bcf"
|
||||
parsed.save(modified_path)
|
||||
with BcfXml.load(modified_path, xml_handler=xml_handler) as modified_parsed:
|
||||
assert modified_parsed == bcf
|
||||
parsed_th = modified_parsed.topics[orig_th.guid]
|
||||
assert parsed_th.markup != orig_th.markup
|
||||
assert parsed_th.markup == parsed.topics[orig_th.guid].markup
|
||||
assert parsed_th.viewpoints == orig_th.viewpoints
|
||||
assert parsed_th.bim_snippet == orig_th.bim_snippet
|
||||
_assert_modified_parsed(modified_parsed, bcf, orig_th, parsed)
|
||||
|
||||
|
||||
def _assert_modified_parsed(modified_parsed, bcf, orig_th, parsed):
|
||||
assert modified_parsed == bcf
|
||||
parsed_th = modified_parsed.topics[orig_th.guid]
|
||||
assert parsed_th.markup != orig_th.markup
|
||||
assert parsed_th.markup == parsed.topics[orig_th.guid].markup
|
||||
assert parsed_th.viewpoints == orig_th.viewpoints
|
||||
assert parsed_th.bim_snippet == orig_th.bim_snippet
|
||||
|
||||
|
||||
def test_bcf_edit(xml_handler, build_sample) -> None:
|
||||
@@ -67,13 +71,8 @@ def test_bcf_edit(xml_handler, build_sample) -> None:
|
||||
th.topic.title = "New Topic Title"
|
||||
parsed.save()
|
||||
with BcfXml.load(file_path, xml_handler=xml_handler) as modified_parsed:
|
||||
assert modified_parsed == bcf
|
||||
_assert_modified_parsed(modified_parsed, bcf, orig_th, parsed)
|
||||
assert len(modified_parsed.topics) == 1
|
||||
parsed_th = modified_parsed.topics[orig_th.guid]
|
||||
assert parsed_th.markup != orig_th.markup
|
||||
assert parsed_th.markup == parsed.topics[orig_th.guid].markup
|
||||
assert parsed_th.viewpoints == orig_th.viewpoints
|
||||
assert parsed_th.bim_snippet == orig_th.bim_snippet
|
||||
|
||||
|
||||
def test_save_no_filename(build_sample) -> None:
|
||||
@@ -88,7 +87,7 @@ def test_load_no_filename() -> None:
|
||||
|
||||
|
||||
def test_save_keep_open(build_sample) -> None:
|
||||
bcf, orig_th = build_sample
|
||||
bcf, _ = build_sample
|
||||
with TemporaryDirectory() as tmp_dir:
|
||||
file_path = Path(tmp_dir) / "test.bcf"
|
||||
bcf.save(file_path, keep_open=True)
|
||||
@@ -96,11 +95,6 @@ def test_save_keep_open(build_sample) -> None:
|
||||
bcf._zip_file.close()
|
||||
|
||||
|
||||
# image = PIL.Image.new('RGB', size=(100, 100))
|
||||
# file = BinaryIO()
|
||||
# image.save(file)
|
||||
|
||||
|
||||
def test_massive_bcf(xml_handler) -> None:
|
||||
ext = mdl.Extensions(topic_types=mdl.ExtensionsTopicTypes(topic_type=["Test type"]))
|
||||
bcf = BcfXml.create_new("Test project", extensions=ext, xml_handler=xml_handler)
|
||||
@@ -119,11 +113,9 @@ def test_massive_bcf(xml_handler) -> None:
|
||||
bcf.save(file_path)
|
||||
|
||||
|
||||
def test_equality_with_wrong_object() -> None:
|
||||
with pytest.raises(TypeError):
|
||||
build_sample[0] == "Wrong object"
|
||||
def test_equality_with_wrong_object(build_sample) -> None:
|
||||
assert build_sample[0] != "Wrong object"
|
||||
|
||||
|
||||
def test_topic_equality_with_wrong_object() -> None:
|
||||
with pytest.raises(TypeError):
|
||||
build_sample[1] == "Wrong object"
|
||||
def test_topic_equality_with_wrong_object(build_sample) -> None:
|
||||
assert build_sample[1] != "Wrong object"
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from bcf.v3.bcfxml import BcfXml
|
||||
|
||||
|
||||
def test_create_clash_set_bcf() -> None:
|
||||
bcfxml = BcfXml.create_new("Clash Test")
|
||||
topic = bcfxml.add_topic("Test", "Test topic", "IfcClash")
|
||||
topic.add_viewpoint_from_point_and_guids(
|
||||
np.array([10, 10, 10]),
|
||||
"firstId",
|
||||
"secondId",
|
||||
)
|
||||
assert len(topic.viewpoints) == 1
|
||||
guid, vi_handler = next((k, v) for k, v in topic.viewpoints.items())
|
||||
v_info = vi_handler.visualization_info
|
||||
assert f"{v_info.guid}.bcfv" == guid
|
||||
components = v_info.components.selection.component
|
||||
assert {c.ifc_guid for c in components} == {"firstId", "secondId"}
|
||||
camera = v_info.perspective_camera
|
||||
viewpoint = camera.camera_view_point
|
||||
assert viewpoint.x == 15
|
||||
assert viewpoint.y == 15
|
||||
assert viewpoint.z == 15
|
||||
# default direction is the unit vector of -1, -1, -1
|
||||
direction = camera.camera_direction
|
||||
assert direction.x == pytest.approx(-1 / 3**0.5)
|
||||
assert direction.y == pytest.approx(-1 / 3**0.5)
|
||||
assert direction.z == pytest.approx(-1 / 3**0.5)
|
||||
# default
|
||||
up_vector = camera.camera_up_vector
|
||||
assert up_vector.x == pytest.approx(-1 / 6**0.5)
|
||||
assert up_vector.y == pytest.approx(-1 / 6**0.5)
|
||||
assert up_vector.z == pytest.approx(1 / 1.5**0.5)
|
||||
assert camera.field_of_view == 60
|
||||
@@ -0,0 +1,26 @@
|
||||
# This CITATION.cff file was generated with cffinit.
|
||||
# Visit https://bit.ly/cffinit to generate yours today!
|
||||
|
||||
cff-version: 1.2.0
|
||||
title: BlenderBIM Add-on
|
||||
message: >-
|
||||
If you use this software, please cite it using the
|
||||
metadata from this file.
|
||||
type: software
|
||||
authors:
|
||||
- name: "IfcOpenShell contributors"
|
||||
repository-code: >-
|
||||
https://github.com/IfcOpenShell/IfcOpenShell/tree/v0.7.0/src/blenderbim
|
||||
url: 'https://blenderbim.org/'
|
||||
repository-artifact: 'https://blenderbim.org/download.html'
|
||||
abstract: >-
|
||||
Add-on to Blender providing a graphical native IFC
|
||||
authoring platform
|
||||
keywords:
|
||||
- IFC
|
||||
- Blender
|
||||
- NativeIFC
|
||||
license: GPL-3.0-or-later
|
||||
commit: 1fb6dac
|
||||
version: v0.0.230506
|
||||
date-released: '2023-05-23'
|
||||
@@ -1,5 +1,5 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
# Copyright (C) 2020-2023 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
@@ -16,7 +16,8 @@
|
||||
# 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/>.
|
||||
|
||||
PYTHON:=python
|
||||
PYTHON:=python3.10
|
||||
PIP:=pip3.10
|
||||
PATCH:=patch
|
||||
SED:=sed -i
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@@ -35,142 +36,122 @@ endif
|
||||
endif
|
||||
|
||||
VERSION:=`date '+%y%m%d'`
|
||||
PYVERSION:=py37
|
||||
PYVERSION:=py310
|
||||
|
||||
ifeq ($(PYVERSION), py37)
|
||||
PYLIBDIR:=python3.7
|
||||
PYNUMBER:=37
|
||||
endif
|
||||
ifeq ($(PYVERSION), py39)
|
||||
PYLIBDIR:=python3.9
|
||||
PYNUMBER:=39
|
||||
endif
|
||||
ifeq ($(PYVERSION), py310)
|
||||
PYLIBDIR:=python3.10
|
||||
PYNUMBER:=31
|
||||
PYNUMBER:=310
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), linux)
|
||||
ifeq ($(PYVERSION), py37)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/linux-64/hpp-fcl-1.7.5-py37h5f1835d_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/linux-64/eigenpy-2.6.5-py37h95e2c48_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/linux-64/boost-1.74.0-py37h0379df6_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/30/c0/d0526314971fc661b083ab135747dc68446a3022686da8c16d25fcf6ef07/lxml-4.6.3-cp37-cp37m-manylinux2014_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/a2/73/07f507b539527579c026ed5f411c35e287685ce794c4dfb7edf6675cdc24/Shapely-1.8.4-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/ed/d5/c2e84e1e36ab8ebea033921d5886a056c77e18bab5ab1051fcc22de2e8a2/Pillow-9.2.0-cp37-cp37m-manylinux_2_28_x86_64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py39)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/linux-64/hpp-fcl-1.7.5-py39hbcdfc36_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/linux-64/eigenpy-2.6.5-py39h5aed9d1_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/linux-64/boost-1.74.0-py39h5472131_3.tar.bz2
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/2.3.4/download/linux-64/hpp-fcl-2.3.4-py39h40a70d0_0.conda
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/3.1.0/download/linux-64/eigenpy-3.1.0-py39hdfdd6bb_0.conda
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/linux-64/boost-1.78.0-py39h7c9e3ff_4.tar.bz2
|
||||
QHULL_URL:=https://anaconda.org/conda-forge/qhull/2020.2/download/linux-64/qhull-2020.2-h4bd325d_2.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/19/d9/a69c6aff5673554df48120565a14a50eaa41d29ae03b02faa0b023666318/lxml-4.6.3-cp39-cp39-manylinux2014_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/08/12/5af915b2bc0470f4a652ef9978557a0fa8b705b122ccaec6626029e1674c/Shapely-1.8.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/2d/f2/8ec281d357e8bb7d08dc8d727f0e4c8ef3dae7d3fa75c69c8e452bb82d50/shapely-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/01/61/3ff85fb4bb596ce3d223c8fcf93c8df5c12bc8899dfb4fb3cb1c5b20dd5f/Pillow-9.2.0-cp39-cp39-manylinux_2_28_x86_64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py310)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.8.0/download/linux-64/hpp-fcl-1.8.0-py310hdaf7e41_1.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.11/download/linux-64/eigenpy-2.6.11-py310hf3e5c9c_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/linux-64/boost-1.74.0-py310h7c3ba0c_5.tar.bz2
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/2.3.4/download/linux-64/hpp-fcl-2.3.4-py310h995690b_0.conda
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/3.1.0/download/linux-64/eigenpy-3.1.0-py310hf02b7e0_0.conda
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/linux-64/boost-1.78.0-py310hc4a4660_4.tar.bz2
|
||||
QHULL_URL:=https://anaconda.org/conda-forge/qhull/2020.2/download/linux-64/qhull-2020.2-h4bd325d_2.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/25/1e/19b46d8e8881fe0df2e20945d51919eeb1817836d62a90efa8506530e45c/lxml-4.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/60/20/c6321e3da92a4ad9495727c9aa8c423e47295572ccd35ece82d1ac013e28/Shapely-1.8.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/a8/a5/403728b5614b28083f6424dfdefec5fcf58068495fb03bb08532671c642f/shapely-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/f6/51/320986ebd6d46a0e95c2240468ced73153b691ce07617078bcdf30c609ec/Pillow-9.2.0-cp310-cp310-manylinux_2_28_x86_64.whl
|
||||
endif
|
||||
ASSIMP_URL:=https://anaconda.org/conda-forge/assimp/5.0.1/download/linux-64/assimp-5.0.1-hedfc422_6.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.7/download/linux-64/octomap-1.9.7-h4bd325d_0.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.8/download/linux-64/octomap-1.9.8-h924138e_0.tar.bz2
|
||||
BOOSTCPP_URL:=https://anaconda.org/conda-forge/boost-cpp/1.78.0/download/linux-64/boost-cpp-1.78.0-h6582d0a_3.conda
|
||||
ZLIB_URL:=https://anaconda.org/conda-forge/zlib/1.2.11/download/linux-64/zlib-1.2.11-h516909a_1010.tar.bz2
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), macos)
|
||||
ifeq ($(PYVERSION), py37)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/osx-64/hpp-fcl-1.7.5-py37h2d7f23a_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/osx-64/eigenpy-2.6.5-py37h0695097_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/osx-64/boost-1.74.0-py37hd79e0ac_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/1e/3e/f0abc15d5dac50939bccc589aae336d5ead4c72e7ad1039a2e0f3630ea92/lxml-4.6.3-cp37-cp37m-macosx_10_9_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/47/a9/7c644e71638bff2bbaa87f05ee62fdf6b4552a55e74bbf731d6210b6d436/Shapely-1.8.4-cp37-cp37m-macosx_10_9_x86_64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/88/49/c26fc3b5b0e82bdc9d8751d6b939da29327b0d98f7c3b95a575cbfed2743/Pillow-9.2.0-cp37-cp37m-macosx_10_10_x86_64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py39)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/osx-64/hpp-fcl-1.7.5-py39h1e32b98_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/osx-64/eigenpy-2.6.5-py39h5405915_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/osx-64/boost-1.74.0-py39ha641261_3.tar.bz2
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/2.3.4/download/osx-64/hpp-fcl-2.3.4-py39hd85b194_0.conda
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/3.1.0/download/osx-64/eigenpy-3.1.0-py39hc4d6e28_0.conda
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/osx-64/boost-1.78.0-py39h953a6b8_4.tar.bz2
|
||||
QHULL_URL:=https://anaconda.org/conda-forge/qhull/2020.2/download/osx-64/qhull-2020.2-h940c156_2.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/b8/74/a71f7ad72e8db54ce899efab84507b801660750cbbfa6a39e6717557d36a/lxml-4.6.3-cp39-cp39-macosx_10_9_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/f5/f9/bf6cc34b02b3c7d3777c5e47fa57d2f69387613bbd8decdf3577a9d83a83/Shapely-1.8.4-cp39-cp39-macosx_10_9_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/36/a4/7e542a209f862f967d7cb8e939eff155f4294a27d17e16441fb8bdd51a2c/shapely-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/88/7a/ddfe28b485b623361457d4783007c1f9ba83a87f93e7fec32f64793efb6c/Pillow-9.2.0-cp39-cp39-macosx_10_10_x86_64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py310)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.8.0/download/osx-64/hpp-fcl-1.8.0-py310h651ac30_1.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.11/download/osx-64/eigenpy-2.6.11-py310hc03097c_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/osx-64/boost-1.74.0-py310h509978a_5.tar.bz2
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/2.3.4/download/osx-64/hpp-fcl-2.3.4-py310h1db6f5f_0.conda
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/3.1.0/download/osx-64/eigenpy-3.1.0-py310h43da829_0.conda
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/osx-64/boost-1.78.0-py310h3e792ce_4.tar.bz2
|
||||
QHULL_URL:=https://anaconda.org/conda-forge/qhull/2020.2/download/osx-64/qhull-2020.2-h940c156_2.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/a1/44/17b7dac7a18807d30e2fe10c3328c152808f5464565e230bfd0e77f178c6/lxml-4.8.0-cp310-cp310-macosx_10_15_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/f5/a8/02347c450b5507b9a7a2c15ad6a029613149468fc55ac2100ab215666159/Shapely-1.8.4-cp310-cp310-macosx_10_9_x86_64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/1f/2a/dc3353c2431cf53e8d04bb8fba27e584410ca3435c9c85f76d71bf0c0e80/shapely-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/d8/60/b13c00d403f34110e96c1b5c0afa73ce461efe3fe960c3a7e3e7fe190d82/Pillow-9.2.0-cp310-cp310-macosx_10_10_x86_64.whl
|
||||
endif
|
||||
ASSIMP_URL:=https://anaconda.org/conda-forge/assimp/5.0.1/download/osx-64/assimp-5.0.1-h1224e73_6.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.7/download/osx-64/octomap-1.9.7-h940c156_0.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.8/download/osx-64/octomap-1.9.8-hb8565cd_0.tar.bz2
|
||||
BOOSTCPP_URL:=https://anaconda.org/conda-forge/boost-cpp/1.78.0/download/osx-64/boost-cpp-1.78.0-hf5ba120_3.conda
|
||||
ZLIB_URL:=https://anaconda.org/conda-forge/zlib/1.2.11/download/osx-64/zlib-1.2.11-h7795811_1010.tar.bz2
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
ifeq ($(PYVERSION), py37)
|
||||
# Warning: py37 not supported on Apple M1
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/osx-64/hpp-fcl-1.7.5-py37h2d7f23a_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/osx-64/eigenpy-2.6.5-py37h0695097_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/osx-64/boost-1.74.0-py37hd79e0ac_3.tar.bz2
|
||||
LXML_URL:=https://anaconda.org/conda-forge/lxml/4.9.1/download/osx-64/lxml-4.9.1-py37h994c40b_0.tar.bz2
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/47/a9/7c644e71638bff2bbaa87f05ee62fdf6b4552a55e74bbf731d6210b6d436/Shapely-1.8.4-cp37-cp37m-macosx_10_9_x86_64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/aa/bc/21097cd891dd2fa02f2b3d767e02e883e026482e59d29975d1bc30024aa3/Pillow-9.2.0-cp39-cp39-macosx_11_0_arm64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py39)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/osx-arm64/hpp-fcl-1.7.5-py39ha69f3c1_2.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.7/download/osx-arm64/eigenpy-2.6.7-py39ha69f3c1_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/osx-arm64/boost-1.78.0-py39h2550fe3_0.tar.bz2
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/2.3.4/download/osx-arm64/hpp-fcl-2.3.4-py39hc34188a_0.conda
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/3.1.0/download/osx-arm64/eigenpy-3.1.0-py39h13cfc01_0.conda
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/osx-arm64/boost-1.78.0-py39h99de9ae_4.tar.bz2
|
||||
QHULL_URL:=https://anaconda.org/conda-forge/qhull/2020.2/download/osx-arm64/qhull-2020.2-hc021e02_2.tar.bz2
|
||||
LXML_URL:=https://anaconda.org/conda-forge/lxml/4.9.1/download/osx-arm64/lxml-4.9.1-py39h9eb174b_0.tar.bz2
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/8e/60/8186995a96c5a27c9b79c015bbdd89c6d9a6df9988f86f3f1027ecd4a56a/Shapely-1.8.4-cp39-cp39-macosx_11_0_arm64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/ea/aa/45fbd031edf3149cb767d8b9f9db45d5faf0324d743c6b8fb0298cc022d0/shapely-2.0.1-cp39-cp39-macosx_11_0_arm64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/aa/bc/21097cd891dd2fa02f2b3d767e02e883e026482e59d29975d1bc30024aa3/Pillow-9.2.0-cp39-cp39-macosx_11_0_arm64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py310)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.8.0/download/osx-arm64/hpp-fcl-1.8.0-py310h5699539_2.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.9/download/osx-arm64/eigenpy-2.6.9-py310habfc766_1.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/osx-arm64/boost-1.78.0-py310h4566fd1_0.tar.bz2
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/2.3.4/download/osx-arm64/hpp-fcl-2.3.4-py310h46fc4cd_0.conda
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/3.1.0/download/osx-arm64/eigenpy-3.1.0-py310ha2643af_0.conda
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/osx-arm64/boost-1.78.0-py310h629746b_4.tar.bz2
|
||||
QHULL_URL:=https://anaconda.org/conda-forge/qhull/2020.2/download/osx-arm64/qhull-2020.2-hc021e02_2.tar.bz2
|
||||
LXML_URL:=https://anaconda.org/conda-forge/lxml/4.9.1/download/osx-arm64/lxml-4.9.1-py310h02f21da_0.tar.bz2
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/ba/d0/75cd36c81a1aa26dd6d37cf7ae1c79b0bc2d379e0f32c359bcb00b14e5c3/Shapely-1.8.4-cp310-cp310-macosx_11_0_arm64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/ec/41/d59208743e737184e1b403e95a937aebb022b8459e99efbcd5208fc8be46/shapely-2.0.1-cp310-cp310-macosx_11_0_arm64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/0c/5f/117b653cad585f3aedfe0de996c292e67d4b020ed77f652e5a6c8c24f908/Pillow-9.2.0-cp310-cp310-macosx_11_0_arm64.whl
|
||||
endif
|
||||
ASSIMP_URL:=https://anaconda.org/conda-forge/assimp/5.0.1/download/osx-arm64/assimp-5.0.1-h0f81e16_7.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.7/download/osx-arm64/octomap-1.9.7-hc021e02_0.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.8/download/osx-arm64/octomap-1.9.8-hffc8910_0.tar.bz2
|
||||
BOOSTCPP_URL:=https://anaconda.org/conda-forge/boost-cpp/1.78.0/download/osx-arm64/boost-cpp-1.78.0-h9ed8d21_3.conda
|
||||
ZLIB_URL:=https://anaconda.org/conda-forge/zlib/1.2.11/download/osx-arm64/zlib-1.2.11-h90dfc92_1014.tar.bz2
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), win)
|
||||
ifeq ($(PYVERSION), py37)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/win-64/hpp-fcl-1.7.5-py37h839d6b1_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/win-64/eigenpy-2.6.5-py37h2c32e34_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/win-64/boost-1.74.0-py37h3b38789_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/9e/5e/171ee9d40a600f565fe691ec5bf7596247ec62cfb2edc00c91afe8ea837b/lxml-4.6.3-cp37-cp37m-win_amd64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/ca/4d/85b912d7947261e6b3218b01946bcd7c2efb2bbafaf517c6fe1dc3bb8399/Shapely-1.8.4-cp37-cp37m-win_amd64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/69/f5/9e802159d78b2eaf26bf1f8b94648605993f5ca7247ac8870f065063fc40/Pillow-9.2.0-cp37-cp37m-win_amd64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py39)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/win-64/hpp-fcl-1.7.5-py39h2e7c763_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/win-64/eigenpy-2.6.5-py39h3ce40e6_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/win-64/boost-1.74.0-py39hefe7e4c_3.tar.bz2
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/2.3.4/download/win-64/hpp-fcl-2.3.4-py39h39b25cb_0.conda
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/3.1.0/download/win-64/eigenpy-3.1.0-py39hb6c915b_0.conda
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/win-64/boost-1.78.0-py39hea4d8d1_4.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/72/d4/426ecb8849c47c3e370c87aa0ac05d85768df917ffea27fcd6686a5e6495/lxml-4.6.3-cp39-cp39-win_amd64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/72/c3/0d52812db25ca71203f6203891277e6ee4f0244b21a36c062123ece15f36/Shapely-1.8.4-cp39-cp39-win_amd64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/a7/ae/eab645c4075093584b7a65ab71cb8ff4563a015bd935c9b55dba14b2c1eb/shapely-2.0.1-cp39-cp39-win_amd64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/19/3f/b4d4bcf05dbcbe07f2e9613a8f4180c297395e73a91d8ad22c32c6624f8c/Pillow-9.2.0-cp39-cp39-win_amd64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py310)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.8.0/download/win-64/hpp-fcl-1.8.0-py310hc5a3c62_1.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.11/download/win-64/eigenpy-2.6.11-py310hbd43d28_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/win-64/boost-1.74.0-py310hc781a3c_5.tar.bz2
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/2.3.4/download/win-64/hpp-fcl-2.3.4-py310heb59267_0.conda
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/3.1.0/download/win-64/eigenpy-3.1.0-py310hd146abe_0.conda
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.78.0/download/win-64/boost-1.78.0-py310h220cb41_4.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/f6/71/65c80a4caa1617a4c6e8fe1500cebb179db96232e2f623bfe6a1f4294e39/lxml-4.8.0-cp310-cp310-win_amd64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/24/b5/46d13799804b5fe9ede2eca8b19023410e29b78baca0bff727671a1df8c1/Shapely-1.8.4-cp310-cp310-win_amd64.whl
|
||||
SHAPELY_URL:=https://files.pythonhosted.org/packages/81/8a/7ac076a86b2632f1872284c5e60ed5f2fc26094875a85b35d9fa17b52504/shapely-2.0.1-cp310-cp310-win_amd64.whl
|
||||
PILLOW_URL:=https://files.pythonhosted.org/packages/02/55/67a3c17b9e7d972ed8c246f104da99ca4f3ea42fba566697e479011b84b6/Pillow-9.2.0-cp310-cp310-win_amd64.whl
|
||||
endif
|
||||
ASSIMP_URL:=https://anaconda.org/conda-forge/assimp/5.0.1/download/win-64/assimp-5.0.1-hc2aa0de_6.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.7/download/win-64/octomap-1.9.7-h5362a0b_0.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.8/download/win-64/octomap-1.9.8-h91493d7_0.tar.bz2
|
||||
BOOSTCPP_URL:=https://anaconda.org/conda-forge/boost-cpp/1.78.0/download/win-64/boost-cpp-1.78.0-h9f4b32c_3.conda
|
||||
ZLIB_URL:=https://anaconda.org/conda-forge/zlib/1.2.11/download/win-64/zlib-1.2.11-h62dcd97_1010.tar.bz2
|
||||
endif
|
||||
|
||||
.PHONY: bump
|
||||
bump:
|
||||
cd . && $(SED) "s/$(OLD)/$(NEW)/" Makefile
|
||||
cd ../ifcopenshell-python/ && $(SED) "s/$(OLD)/$(NEW)/" Makefile
|
||||
cd ../ifcopenshell-python/docs/ifcconvert/ && $(SED) "s/$(OLD)/$(NEW)/" installation.rst
|
||||
cd ../ifcopenshell-python/docs/ifcopenshell-python/ && $(SED) "s/$(OLD)/$(NEW)/" installation.rst
|
||||
|
||||
.PHONY: dist
|
||||
dist:
|
||||
ifndef PLATFORM
|
||||
@@ -182,7 +163,7 @@ endif
|
||||
cp -r blenderbim/* dist/blenderbim/
|
||||
|
||||
# Provides IfcOpenShell Python functionality
|
||||
cd dist/working && wget https://s3.amazonaws.com/ifcopenshell-builds/ifcopenshell-python-$(PYNUMBER)-v0.7.0-cdde536-$(PLATFORM)64.zip
|
||||
cd dist/working && wget https://s3.amazonaws.com/ifcopenshell-builds/ifcopenshell-python-$(PYNUMBER)-v0.7.0-fc50bdd-$(PLATFORM)64.zip
|
||||
cd dist/working && unzip ifcopenshell-python*
|
||||
cp -r dist/working/ifcopenshell dist/blenderbim/libs/site/packages/
|
||||
|
||||
@@ -198,16 +179,16 @@ endif
|
||||
# IfcOpenBot sometimes lags behind, so we hotfix the Python utilities
|
||||
cp -r dist/working/IfcOpenShell-0.7.0/src/ifcopenshell-python/ifcopenshell/util/* dist/blenderbim/libs/site/packages/ifcopenshell/util/
|
||||
cp -r dist/working/IfcOpenShell-0.7.0/src/ifcopenshell-python/ifcopenshell/api/* dist/blenderbim/libs/site/packages/ifcopenshell/api/
|
||||
cp dist/working/IfcOpenShell-0.7.0/src/ifcopenshell-python/ifcopenshell/entity_instance.py dist/blenderbim/libs/site/packages/ifcopenshell/
|
||||
cp dist/working/IfcOpenShell-0.7.0/src/ifcopenshell-python/ifcopenshell/file.py dist/blenderbim/libs/site/packages/ifcopenshell/
|
||||
cp dist/working/IfcOpenShell-0.7.0/src/ifcopenshell-python/ifcopenshell/*.py dist/blenderbim/libs/site/packages/ifcopenshell/
|
||||
cp dist/working/IfcOpenShell-0.7.0/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py dist/blenderbim/libs/site/packages/ifcopenshell/express/
|
||||
# Provides bcf functionality
|
||||
cp -r dist/working/IfcOpenShell-0.7.0/src/bcf/src/bcf dist/blenderbim/libs/site/packages/
|
||||
# Provides IFCClash functionality
|
||||
cp -r dist/working/IfcOpenShell-0.7.0/src/ifcclash/ifcclash dist/blenderbim/libs/site/packages/
|
||||
# Provides BIMTester functionality
|
||||
cd dist/working && $(PYTHON) -m venv env
|
||||
cd dist/working && . env/bin/activate && pip install pybabel
|
||||
cd dist/working && . env/bin/activate && pip install babel
|
||||
cd dist/working && . env/bin/activate && $(PIP) install pybabel
|
||||
cd dist/working && . env/bin/activate && $(PIP) install babel
|
||||
cd dist/working && . env/bin/activate && ./env/bin/pybabel compile -d ./IfcOpenShell-0.7.0/src/ifcbimtester/bimtester/locale/
|
||||
cp -r dist/working/IfcOpenShell-0.7.0/src/ifcbimtester/bimtester dist/blenderbim/libs/site/packages/
|
||||
# Provides IFCTester functionality
|
||||
@@ -226,9 +207,15 @@ endif
|
||||
cp -r dist/working/IfcOpenShell-0.7.0/src/ifc5d/ifc5d dist/blenderbim/libs/site/packages/
|
||||
# Provides IFCCityJSON functionality
|
||||
cp -r dist/working/IfcOpenShell-0.7.0/src/ifccityjson dist/blenderbim/libs/site/packages/
|
||||
# Provides IfcGit functionality
|
||||
cd dist/working && . env/bin/activate && $(PIP) install GitPython --target=./site-packages
|
||||
cp -r dist/working/site-packages/smmap dist/blenderbim/libs/site/packages/
|
||||
cp -r dist/working/site-packages/gitdb dist/blenderbim/libs/site/packages/
|
||||
cp -r dist/working/site-packages/git dist/blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Provides Mustache templating in construction documentation
|
||||
# TODO: remove this dependency, it seems overkill and we seem to get by with str replaces
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://files.pythonhosted.org/packages/3f/e7/8750ba6c6101d6aa5ceeb20c013adf2c6f3554a12c71d75654b468404bfa/pystache-0.6.0.tar.gz
|
||||
cd dist/working && tar -xzvf pystache*
|
||||
@@ -270,6 +257,13 @@ endif
|
||||
cp -r dist/working/decorator-5.0.9/src/decorator.py dist/blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Provides audio playback for costing
|
||||
mkdir -p dist/working
|
||||
git clone https://github.com/Andrej730/aud.git --branch master-reduced-size --depth 1 dist/working/aud
|
||||
cd dist/working/aud && git checkout 529af208fbcb707c387bfb681d2605c0b6112de7
|
||||
cp -r dist/working/aud/aud dist/blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Provides jsgantt-improved supports for web-based construction sequencing gantt charts
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://raw.githubusercontent.com/jsGanttImproved/jsgantt-improved/master/dist/jsgantt.js
|
||||
@@ -353,10 +347,10 @@ endif
|
||||
cd dist/working && cp *.whl shapely.zip && unzip shapely.zip
|
||||
cp -r dist/working/shapely dist/blenderbim/libs/site/packages/
|
||||
ifeq ($(PLATFORM), win)
|
||||
cp -r dist/working/Shapely.libs dist/blenderbim/libs/site/packages/
|
||||
cp -r dist/working/shapely.libs dist/blenderbim/libs/site/packages/
|
||||
endif
|
||||
ifeq ($(PLATFORM), linux)
|
||||
cp -r dist/working/Shapely.libs dist/blenderbim/libs/site/packages/
|
||||
cp -r dist/working/shapely.libs dist/blenderbim/libs/site/packages/
|
||||
endif
|
||||
rm -rf dist/working
|
||||
|
||||
@@ -378,19 +372,23 @@ endif
|
||||
cp -r dist/working/tqdm-4.50.0/tqdm dist/blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by IFCCityJSON
|
||||
mkdir dist/working
|
||||
cd dist/working && $(PYTHON) -m venv env
|
||||
cd dist/working && mkdir site-packages
|
||||
cd dist/working && . env/bin/activate && pip install cjio --target=./site-packages
|
||||
cd dist/working/site-packages/ && rm -r *dist-info*
|
||||
# Required by IFCCityJSON
|
||||
cd dist/working && . env/bin/activate && $(PIP) install cjio --target=./site-packages
|
||||
# Provides express rule validation for ifcopenshell.validate
|
||||
cd dist/working && . env/bin/activate && $(PIP) install pytest --target=./site-packages
|
||||
# Provides Brickschema functionality
|
||||
cd dist/working && . env/bin/activate && $(PIP) install brickschema[persistence] --target=./site-packages
|
||||
cp -r dist/working/site-packages/* dist/blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by IFCClash
|
||||
mkdir dist/working
|
||||
cd dist/working && wget $(HPPFCL_URL)
|
||||
cd dist/working && tar -xf hpp-fcl*
|
||||
cd dist/working && unzip hpp-fcl*
|
||||
cd dist/working && tar -I zstd -xvf pkg*
|
||||
ifeq ($(PLATFORM), linux)
|
||||
cp -r dist/working/lib/$(PYLIBDIR)/site-packages/hppfcl dist/blenderbim/libs/site/packages/
|
||||
cp -r dist/working/lib/*.so* dist/blenderbim/libs/
|
||||
@@ -399,6 +397,10 @@ ifeq ($(PLATFORM), macos)
|
||||
cp -r dist/working/lib/$(PYLIBDIR)/site-packages/hppfcl dist/blenderbim/libs/site/packages/
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
cp -r dist/working/lib/$(PYLIBDIR)/site-packages/hppfcl dist/blenderbim/libs/site/packages/
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), win)
|
||||
cp -r dist/working/Lib/site-packages/hppfcl dist/blenderbim/libs/site/packages/
|
||||
cp -r dist/working/Library/bin/*.dll dist/blenderbim/libs/site/packages/hppfcl/
|
||||
@@ -415,21 +417,45 @@ endif
|
||||
ifeq ($(PLATFORM), macos)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), win)
|
||||
cp -r dist/working/Library/bin/*.dll dist/blenderbim/libs/site/packages/hppfcl/
|
||||
endif
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by hpp-fcl
|
||||
# Required by hpp-fcl except on Windows
|
||||
ifneq ($(PLATFORM), win)
|
||||
mkdir dist/working
|
||||
cd dist/working && wget $(EIGENPY_URL)
|
||||
cd dist/working && tar -xf eigenpy*
|
||||
cd dist/working && wget $(QHULL_URL)
|
||||
cd dist/working && tar -xf qhull*
|
||||
ifeq ($(PLATFORM), linux)
|
||||
cp -r dist/working/lib/*.so* dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macos)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
rm -rf dist/working
|
||||
endif
|
||||
|
||||
# Required by hpp-fcl
|
||||
mkdir dist/working
|
||||
cd dist/working && wget $(EIGENPY_URL)
|
||||
cd dist/working && unzip eigenpy*
|
||||
cd dist/working && tar -I zstd -xvf pkg*
|
||||
ifeq ($(PLATFORM), linux)
|
||||
cp -r dist/working/lib/*.so* dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macos)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), win)
|
||||
cp -r dist/working/Library/bin/*.dll dist/blenderbim/libs/site/packages/hppfcl/
|
||||
endif
|
||||
@@ -445,6 +471,9 @@ endif
|
||||
ifeq ($(PLATFORM), macos)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), win)
|
||||
# Uh, do nothing, apparently? No DLLs are shipped.
|
||||
endif
|
||||
@@ -460,11 +489,33 @@ endif
|
||||
ifeq ($(PLATFORM), macos)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), win)
|
||||
cp -r dist/working/Library/bin/*.dll dist/blenderbim/libs/site/packages/hppfcl/
|
||||
endif
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by hpp-fcl
|
||||
mkdir dist/working
|
||||
cd dist/working && wget $(BOOSTCPP_URL)
|
||||
cd dist/working && unzip boost-cpp*
|
||||
cd dist/working && tar -I zstd -xvf pkg*
|
||||
ifeq ($(PLATFORM), linux)
|
||||
cp -r dist/working/lib/libboost_serialization.so* dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macos)
|
||||
cp -r dist/working/lib/libboost_serialization.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
cp -r dist/working/lib/libboost_serialization.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), win)
|
||||
cp -r dist/working/Library/bin/boost_serialization.dll dist/blenderbim/libs/site/packages/hppfcl/
|
||||
endif
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by hpp-fcl
|
||||
mkdir dist/working
|
||||
cd dist/working && wget $(ZLIB_URL)
|
||||
@@ -475,6 +526,9 @@ endif
|
||||
ifeq ($(PLATFORM), macos)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), macosm1)
|
||||
cp -r dist/working/lib/*.dylib dist/blenderbim/libs/
|
||||
endif
|
||||
ifeq ($(PLATFORM), win)
|
||||
cp -r dist/working/Library/bin/*.dll dist/blenderbim/libs/site/packages/hppfcl/
|
||||
endif
|
||||
@@ -528,6 +582,7 @@ endif
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by IFCCOBie for XLSX support
|
||||
# TODO: see if we can replace this with openpyxl which does both read/write
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://files.pythonhosted.org/packages/0c/bc/82d6783f83f65f56d8b77d052773c4a2f952fa86385f0cd54e1e006658d7/XlsxWriter-1.2.9.tar.gz
|
||||
cd dist/working && tar -xzvf XlsxWriter*
|
||||
@@ -592,35 +647,9 @@ endif
|
||||
|
||||
# Provides Brickschema functionality
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://files.pythonhosted.org/packages/ca/37/8309da9a72407d2f5eb5489c197ac3cfe96ee3ccba1902d2a0ecc7843f92/brickschema-0.5.1.tar.gz
|
||||
cd dist/working && tar -xzvf brickschema*
|
||||
# This is an evil hack because we don't want to bundle flask
|
||||
echo "" > dist/working/brickschema-0.5.1/brickschema/web.py
|
||||
cd dist/working/brickschema-0.5.1/ && cp -r brickschema ../../blenderbim/libs/site/packages/
|
||||
# For now lets bundle the latest nightly schema
|
||||
cd dist/working && wget https://github.com/BrickSchema/Brick/releases/download/nightly/Brick.ttl
|
||||
cd dist/working && cp Brick.ttl ../../blenderbim/bim/schema/Brick.ttl
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by brickschema
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://files.pythonhosted.org/packages/c7/22/37bb938be8e5c20d443b0c9ba0a243573b671b01739efb0a19f81bc5b470/pyshacl-0.17.2.tar.gz
|
||||
cd dist/working && tar -xzvf pyshacl*
|
||||
cd dist/working/pyshacl-0.17.2/ && cp -r pyshacl ../../blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by brickschema
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://files.pythonhosted.org/packages/d2/a7/be8244688bfcee37c23733ab4fe8e6afa6d4403bd2674a3ae7bd2cecc77b/rdflib-6.0.2.tar.gz
|
||||
cd dist/working && tar -xzvf rdflib*
|
||||
cd dist/working/rdflib-6.0.2/ && cp -r rdflib ../../blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by brickschema
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://files.pythonhosted.org/packages/7d/c7/208aece36279e4f1236e437119358786e39530ecc1719d4e1afeddba5288/owlrl-6.0.2.tar.gz
|
||||
cd dist/working && tar -xzvf owlrl*
|
||||
cd dist/working/owlrl-6.0.2/ && cp -r owlrl ../../blenderbim/libs/site/packages/
|
||||
cd dist/working && cp Brick.ttl ../blenderbim/bim/schema/Brick.ttl
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by brickschema
|
||||
@@ -631,6 +660,20 @@ endif
|
||||
cd dist/working/ && cp -r pkg_resources ../blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Required for hipped roof generation
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://github.com/prochitecture/bpypolyskel/archive/refs/heads/master.zip
|
||||
cd dist/working && unzip master.zip
|
||||
cp -r dist/working/bpypolyskel-master/bpypolyskel dist/blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Required for Desktop icon and file association
|
||||
cp -r blenderbim/libs/desktop dist/blenderbim/libs/
|
||||
|
||||
# Remove dependencies also bundled with Blender
|
||||
rm -rf dist/blenderbim/libs/site/packages/numpy
|
||||
rm -rf dist/blenderbim/libs/site/packages/numpy.libs
|
||||
|
||||
cd dist/blenderbim && $(SED) "s/999999/$(VERSION)/" __init__.py
|
||||
cd dist && zip -r blenderbim-$(VERSION)-$(PYVERSION)-$(PLATFORM).zip ./*
|
||||
rm -rf dist/blenderbim
|
||||
|
||||
@@ -34,7 +34,8 @@ bl_info = {
|
||||
if sys.modules.get("bpy", None):
|
||||
# Process *.pth in /libs/site/packages to setup globally importable modules
|
||||
# This is 3 levels deep as required by the static RPATH of ../../ from dependencies taken from Anaconda
|
||||
site.addsitedir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "libs", "site", "packages"))
|
||||
# site.addsitedir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "libs", "site", "packages"))
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), "libs", "site", "packages"))
|
||||
|
||||
import blenderbim.bim
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import blenderbim
|
||||
import importlib
|
||||
from . import handler, ui, prop, operator, helper
|
||||
|
||||
@@ -70,6 +71,7 @@ modules = {
|
||||
"covetool": None,
|
||||
"augin": None,
|
||||
"debug": None,
|
||||
"ifcgit": None,
|
||||
# Uncomment this line to enable loading of the demo module. Happy hacking!
|
||||
# The name "demo" must correlate to a folder name in `bim/module/`.
|
||||
# "demo": None,
|
||||
@@ -91,7 +93,10 @@ classes = [
|
||||
operator.RemoveIfcFile,
|
||||
operator.SelectDataDir,
|
||||
operator.SelectIfcFile,
|
||||
operator.ReloadSelectedIfcFile,
|
||||
operator.SelectSchemaDir,
|
||||
operator.FileAssociate,
|
||||
operator.FileUnassociate,
|
||||
operator.SelectURIAttribute,
|
||||
operator.EditBlenderCollection,
|
||||
operator.BIM_OT_open_webbrowser,
|
||||
@@ -106,6 +111,7 @@ classes = [
|
||||
prop.PsetQto,
|
||||
prop.GlobalId,
|
||||
prop.BIMObjectProperties,
|
||||
prop.BIMCollectionProperties,
|
||||
prop.BIMMaterialProperties,
|
||||
prop.BIMMeshProperties,
|
||||
ui.BIM_PT_section_plane,
|
||||
@@ -116,6 +122,7 @@ classes = [
|
||||
ui.BIM_PT_project_info,
|
||||
ui.BIM_PT_project_setup,
|
||||
ui.BIM_PT_collaboration,
|
||||
ui.BIM_PT_selection,
|
||||
ui.BIM_PT_geometry,
|
||||
ui.BIM_PT_services,
|
||||
ui.BIM_PT_structural,
|
||||
@@ -150,8 +157,9 @@ def register():
|
||||
bpy.app.handlers.redo_post.append(handler.redo_post)
|
||||
bpy.app.handlers.load_post.append(handler.setDefaultProperties)
|
||||
bpy.app.handlers.load_post.append(handler.loadIfcStore)
|
||||
bpy.app.handlers.save_pre.append(handler.ensureIfcExported)
|
||||
bpy.app.handlers.save_post.append(handler.ensureIfcExported)
|
||||
bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties)
|
||||
bpy.types.Collection.BIMCollectionProperties = bpy.props.PointerProperty(type=prop.BIMCollectionProperties)
|
||||
bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
||||
bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
||||
bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties)
|
||||
@@ -162,6 +170,7 @@ def register():
|
||||
bpy.types.SCENE_PT_unit.append(ui.ifc_units)
|
||||
if hasattr(bpy.types, "UI_MT_button_context_menu"):
|
||||
bpy.types.UI_MT_button_context_menu.append(ui.draw_custom_context_menu)
|
||||
bpy.types.STATUSBAR_HT_header.append(ui.draw_statusbar)
|
||||
|
||||
for mod in modules.values():
|
||||
mod.register()
|
||||
@@ -169,11 +178,16 @@ def register():
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
if getattr(cls, "is_registered", None) is None:
|
||||
bpy.utils.unregister_class(cls)
|
||||
elif cls.is_registered:
|
||||
bpy.utils.unregister_class(cls)
|
||||
|
||||
bpy.app.handlers.load_post.remove(handler.setDefaultProperties)
|
||||
bpy.app.handlers.load_post.remove(handler.loadIfcStore)
|
||||
bpy.app.handlers.save_pre.remove(handler.ensureIfcExported)
|
||||
bpy.app.handlers.save_post.remove(handler.ensureIfcExported)
|
||||
del bpy.types.Scene.BIMProperties
|
||||
del bpy.types.Collection.BIMCollectionProperties
|
||||
del bpy.types.Object.BIMObjectProperties
|
||||
del bpy.types.Material.BIMObjectProperties
|
||||
del bpy.types.Material.BIMMaterialProperties
|
||||
@@ -184,6 +198,7 @@ def unregister():
|
||||
bpy.types.SCENE_PT_unit.remove(ui.ifc_units)
|
||||
if hasattr(bpy.types, "UI_MT_button_context_menu"):
|
||||
bpy.types.UI_MT_button_context_menu.remove(ui.draw_custom_context_menu)
|
||||
bpy.types.STATUSBAR_HT_header.remove(ui.draw_statusbar)
|
||||
|
||||
for mod in reversed(list(modules.values())):
|
||||
mod.unregister()
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
*/
|
||||
|
||||
* { stroke-linecap: round; stroke-linejoin: round; }
|
||||
text { fill: black; stroke: none; }
|
||||
text, tspan { /* 2.5mm */ fill: black; stroke: none; font-family: 'OpenGost Type B TT', 'DejaVu Sans Condensed', 'Liberation Sans', 'Arial Narrow', 'Arial'; font-size: 4.13px; }
|
||||
.cut { fill: black; stroke: black; stroke-linecap: 'round'; stroke-width: 0.35; fill-rule: evenodd; }
|
||||
.projection { fill: white; stroke: black; stroke-linecap: 'round'; stroke-width: 0.25; }
|
||||
.surface { stroke: none; fill: #fff; fill-rule: evenodd; }
|
||||
.annotation { fill: none; stroke: black; stroke-linecap: 'round'; stroke-width: 0.25; }
|
||||
.IfcAnnotation { fill: none; stroke: black; stroke-linecap: 'round'; stroke-width: 0.25; }
|
||||
.IfcGeographicElement { fill: none; stroke: black; stroke-linecap: 'round'; stroke-width: 1; }
|
||||
.PredefinedType-LINEWORK { stroke: black; stroke-width: 0.25; }
|
||||
.PredefinedType-BACKGROUND { stroke: black; stroke-width: 0.18; }
|
||||
.PredefinedType-GRID { marker-start: url(#grid-marker); marker-end: url(#grid-marker); }
|
||||
@@ -32,18 +34,27 @@ text { fill: black; stroke: none; }
|
||||
.PredefinedType-PLANLEVEL { marker-end: url(#plan-level-marker); }
|
||||
.PredefinedType-DIMENSION { marker-start: url(#dimension-marker-start); marker-end: url(#dimension-marker-end); }
|
||||
.PredefinedType-ANGLE { marker-start: url(#angle-marker-start); marker-end: url(#angle-marker-end); }
|
||||
.PredefinedType-RADIUS { marker-end: url(#radius-marker-end); }
|
||||
.PredefinedType-RADIUS { marker-end: url(#fall-marker-end); }
|
||||
.PredefinedType-FALL { marker-end: url(#radius-marker-end); }
|
||||
.PredefinedType-SLOPEANGLE { marker-end: url(#radius-marker-end); }
|
||||
.PredefinedType-SLOPEPERCENT { marker-end: url(#radius-marker-end); }
|
||||
.PredefinedType-SLOPEFRACTION { marker-end: url(#radius-marker-end); }
|
||||
.PredefinedType-DIAMETER { marker-start: url(#diameter-marker-start); marker-end: url(#diameter-marker-end); }
|
||||
.PredefinedType-HIDDENLINE { stroke-dasharray: 3, 2; }
|
||||
.PredefinedType-STAIRARROW { marker-start: url(#stair-marker-start); marker-end: url(#stair-marker-end); }
|
||||
.PredefinedType-BOUNDARY { fill: none; stroke: red; stroke-width: 1; stroke-dasharray: 12, 4, 3, 4, 3, 4; }
|
||||
.PredefinedType-BATTING { marker-start: url(#batting); stroke: none; }
|
||||
.PredefinedType-SEALANT { fill: url(#crosshatch1); stroke-width: 0.25; }
|
||||
.PredefinedType-FILLAREA { fill: white; stroke: none; }
|
||||
.PredefinedType-FILLAREA { fill: white; stroke: black; }
|
||||
.PredefinedType-BREAKLINE { fill: none; stroke: black; stroke-width: 0.25; marker-mid: url(#breakline-marker); }
|
||||
.PredefinedType-TEXT { fill: black; stroke: none; }
|
||||
path.PredefinedType-TEXTLEADER { marker-end: url(#leader-marker); }
|
||||
text.PredefinedType-TEXTLEADER { fill: black; stroke: none; }
|
||||
text.PredefinedType-TEXTLEADER, tspan.PredefinedType-TEXTLEADER { fill: black; stroke: none; }
|
||||
text.title, tspan.title { /* 7mm */ font-size: 11.55px; }
|
||||
text.header, tspan.header { /* 5mm */ font-size: 8.25px; }
|
||||
text.large, tspan.large { /* 3.5mm */ font-size: 5.78px; }
|
||||
text.regular, tspan.regular { /* 2.5mm */ font-size: 4.13px; }
|
||||
text.small, tspan.small { /* 1.8mm */ font-size: 2.97px; }
|
||||
text.GRID, tspan.GRID { /* 5mm */ font-size: 8.25px; }
|
||||
.material-blank { fill: white; }
|
||||
.material-diagonal1 { fill: url(#diagonal1); }
|
||||
.material-diagonal2 { fill: url(#diagonal2); }
|
||||
@@ -1,9 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<svg baseProfile="full" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<marker id="batting" markerHeight="10" markerWidth="4" orient="auto" refX="0" refY="5" markerUnits="userSpaceOnUse">
|
||||
<!-- Tip: https://svg-path-visualizer.netlify.app/ -->
|
||||
<path style="fill: none; stroke:black; stroke-width:0.18" d="M 0 2 A 2 2 0 0 1 4 2 L 2 8 M 0 2 L 2 8 A 2 2 0 0 0 4 10 M 2 8 A 2 2 0 0 1 0 10" />
|
||||
</marker>
|
||||
<!-- Tip: https://www.svgviewer.dev/ -->
|
||||
<marker id="eng-dimension-marker-start" markerHeight="14" markerWidth="11" orient="auto" refX="1" refY="7">
|
||||
<g>
|
||||
<path d="M 11 3.5 L 11 10.5 L 1 7" class="annotation" style="fill:black;" />
|
||||
@@ -21,6 +19,12 @@
|
||||
<path d="M 0 3.5 L 0 10.5 L 10 7" class="annotation" style="fill:black;" />
|
||||
</g>
|
||||
</marker>
|
||||
<!-- same as for the radius -->
|
||||
<marker id="fall-marker-end" markerHeight="14" markerWidth="11" orient="auto" refX="10" refY="7">
|
||||
<g>
|
||||
<path d="M 0 3.5 L 0 10.5 L 10 7" class="annotation" style="fill:black;" />
|
||||
</g>
|
||||
</marker>
|
||||
<marker id="angle-marker-start" markerHeight="14" markerWidth="11" orient="auto" refX="1" refY="7">
|
||||
<g>
|
||||
<path d="M 11 3.5 L 11 10.5 L 1 7" class="annotation" style="fill:black;" />
|
||||
@@ -92,4 +96,12 @@
|
||||
<path d="M 7.5 10 L 10 0 L 15 10" class="annotation" style="stroke-width:1; fill: white;" />
|
||||
</g>
|
||||
</marker>
|
||||
<filter x="0" y="0" width="1" height="1" id="fill-background">
|
||||
<feFlood flood-color="white" result="bg" />
|
||||
<feMerge>
|
||||
<feMergeNode in="bg"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.6 KiB |
@@ -17,16 +17,49 @@
|
||||
<line x1="0" y1="0" x2="0" y2="3" style="stroke:black; stroke-width:0.25" />
|
||||
</pattern>
|
||||
<pattern id="square1" width="1" height="1" patternUnits="userSpaceOnUse">
|
||||
<line x1="0" y1="0" x2="0" y2="1" style="stroke:black; stroke-width:0.25" />
|
||||
<line x1="0" y1="0" x2="1" y2="0" style="stroke:black; stroke-width:0.25" />
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 1 0 1 1" />
|
||||
</pattern>
|
||||
<pattern id="square2" width="2" height="2" patternUnits="userSpaceOnUse">
|
||||
<line x1="0" y1="0" x2="0" y2="2" style="stroke:black; stroke-width:0.25" />
|
||||
<line x1="0" y1="0" x2="2" y2="0" style="stroke:black; stroke-width:0.25" />
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 2 0 2 2" />
|
||||
</pattern>
|
||||
<pattern id="square3" width="3" height="3" patternUnits="userSpaceOnUse">
|
||||
<line x1="0" y1="0" x2="0" y2="3" style="stroke:black; stroke-width:0.25" />
|
||||
<line x1="0" y1="0" x2="3" y2="0" style="stroke:black; stroke-width:0.25" />
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 3 0 3 3" />
|
||||
</pattern>
|
||||
<pattern id="recth1" width="2" height="1" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 2 0 2 1" />
|
||||
</pattern>
|
||||
<pattern id="recth2" width="4" height="2" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 4 0 4 2" />
|
||||
</pattern>
|
||||
<pattern id="recth3" width="6" height="3" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 6 0 6 3" />
|
||||
</pattern>
|
||||
<pattern id="rectv1" width="1" height="2" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 1 0 1 2" />
|
||||
</pattern>
|
||||
<pattern id="rectv2" width="2" height="4" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 2 0 2 4" />
|
||||
</pattern>
|
||||
<pattern id="rectv3" width="3" height="6" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.25; fill: none;" d="M 0 0 3 0 3 6" />
|
||||
</pattern>
|
||||
<pattern id="tile1" width="2" height="2" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.15; fill: none;" d="M 0 0 2 0 2 1 0 1 M 1 1 1 2" />
|
||||
</pattern>
|
||||
<pattern id="tile2" width="4" height="4" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.15; fill: none;" d="M 0 0 4 0 4 2 0 2 M 2 2 2 4" />
|
||||
</pattern>
|
||||
<pattern id="tile3" width="6" height="6" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.15; fill: none;" d="M 0 0 6 0 6 3 0 3 M 3 3 3 6" />
|
||||
</pattern>
|
||||
<pattern id="board1" width="4" height="2" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.15; fill: none;" d="M 0 0 4 0 4 1 0 1 M 2 1 2 2" />
|
||||
</pattern>
|
||||
<pattern id="board2" width="8" height="4" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.15; fill: none;" d="M 0 0 8 0 8 2 0 2 M 4 2 4 4" />
|
||||
</pattern>
|
||||
<pattern id="board3" width="12" height="6" patternUnits="userSpaceOnUse">
|
||||
<path style="stroke: black; stroke-width: 0.15; fill: none;" d="M 0 0 12 0 12 3 0 3 M 6 3 6 6" />
|
||||
</pattern>
|
||||
<pattern id="crosshatch1" width="1" height="1" patternTransform="rotate(45 0 0)" patternUnits="userSpaceOnUse">
|
||||
<line x1="0" y1="0" x2="0" y2="1" style="stroke:black; stroke-width:0.25" />
|
||||
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 69 KiB |
@@ -0,0 +1,755 @@
|
||||
{
|
||||
"Technical": {
|
||||
"render_type": "VIEWPORT",
|
||||
"raster_style": {
|
||||
"bpy.data.worlds[0].color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"scene.render.bake_bias": 0.0010000000474974513,
|
||||
"scene.render.bake_margin": 16,
|
||||
"scene.render.bake_margin_type": "ADJACENT_FACES",
|
||||
"scene.render.bake_samples": 256,
|
||||
"scene.render.bake_type": "NORMALS",
|
||||
"scene.render.bake_user_scale": 0.0,
|
||||
"scene.render.border_max_x": 1.0,
|
||||
"scene.render.border_max_y": 1.0,
|
||||
"scene.render.border_min_x": 0.0,
|
||||
"scene.render.border_min_y": 0.0,
|
||||
"scene.render.dither_intensity": 1.0,
|
||||
"scene.render.engine": "BLENDER_WORKBENCH",
|
||||
"scene.render.film_transparent": false,
|
||||
"scene.render.filter_size": 1.5,
|
||||
"scene.render.fps": 24,
|
||||
"scene.render.fps_base": 1.0,
|
||||
"scene.render.frame_map_new": 100,
|
||||
"scene.render.frame_map_old": 100,
|
||||
"scene.render.hair_subdiv": 0,
|
||||
"scene.render.hair_type": "STRAND",
|
||||
"scene.render.line_thickness": 1.0,
|
||||
"scene.render.line_thickness_mode": "ABSOLUTE",
|
||||
"scene.render.metadata_input": "SCENE",
|
||||
"scene.render.motion_blur_shutter": 0.5,
|
||||
"scene.render.pixel_aspect_x": 1.0,
|
||||
"scene.render.pixel_aspect_y": 1.0,
|
||||
"scene.render.preview_pixel_size": "AUTO",
|
||||
"scene.render.resolution_percentage": 100,
|
||||
"scene.render.resolution_x": 1000,
|
||||
"scene.render.resolution_y": 1000,
|
||||
"scene.render.sequencer_gl_preview": "SOLID",
|
||||
"scene.render.simplify_child_particles": 1.0,
|
||||
"scene.render.simplify_child_particles_render": 1.0,
|
||||
"scene.render.simplify_gpencil": false,
|
||||
"scene.render.simplify_gpencil_antialiasing": true,
|
||||
"scene.render.simplify_gpencil_modifier": true,
|
||||
"scene.render.simplify_gpencil_onplay": false,
|
||||
"scene.render.simplify_gpencil_shader_fx": true,
|
||||
"scene.render.simplify_gpencil_tint": true,
|
||||
"scene.render.simplify_gpencil_view_fill": true,
|
||||
"scene.render.simplify_shadows": 1.0,
|
||||
"scene.render.simplify_shadows_render": 1.0,
|
||||
"scene.render.simplify_subdivision": 6,
|
||||
"scene.render.simplify_subdivision_render": 6,
|
||||
"scene.render.simplify_volumes": 1.0,
|
||||
"scene.render.stamp_font_size": 12,
|
||||
"scene.render.stamp_note_text": "",
|
||||
"scene.render.threads": 20,
|
||||
"scene.render.threads_mode": "AUTO",
|
||||
"scene.render.use_bake_clear": true,
|
||||
"scene.render.use_bake_lores_mesh": false,
|
||||
"scene.render.use_bake_multires": false,
|
||||
"scene.render.use_bake_selected_to_active": false,
|
||||
"scene.render.use_bake_user_scale": false,
|
||||
"scene.render.use_border": false,
|
||||
"scene.render.use_compositing": true,
|
||||
"scene.render.use_crop_to_border": false,
|
||||
"scene.render.use_file_extension": true,
|
||||
"scene.render.use_freestyle": false,
|
||||
"scene.render.use_high_quality_normals": false,
|
||||
"scene.render.use_lock_interface": false,
|
||||
"scene.render.use_motion_blur": false,
|
||||
"scene.render.use_multiview": false,
|
||||
"scene.render.use_overwrite": true,
|
||||
"scene.render.use_persistent_data": false,
|
||||
"scene.render.use_placeholder": false,
|
||||
"scene.render.use_render_cache": false,
|
||||
"scene.render.use_sequencer": true,
|
||||
"scene.render.use_sequencer_override_scene_strip": false,
|
||||
"scene.render.use_simplify": false,
|
||||
"scene.render.use_single_layer": false,
|
||||
"scene.render.use_stamp": false,
|
||||
"scene.render.use_stamp_camera": true,
|
||||
"scene.render.use_stamp_date": true,
|
||||
"scene.render.use_stamp_filename": true,
|
||||
"scene.render.use_stamp_frame": true,
|
||||
"scene.render.use_stamp_frame_range": false,
|
||||
"scene.render.use_stamp_hostname": false,
|
||||
"scene.render.use_stamp_labels": true,
|
||||
"scene.render.use_stamp_lens": false,
|
||||
"scene.render.use_stamp_marker": false,
|
||||
"scene.render.use_stamp_memory": false,
|
||||
"scene.render.use_stamp_note": false,
|
||||
"scene.render.use_stamp_render_time": true,
|
||||
"scene.render.use_stamp_scene": true,
|
||||
"scene.render.use_stamp_sequencer_strip": false,
|
||||
"scene.render.use_stamp_time": true,
|
||||
"scene.render.views_format": "STEREO_3D",
|
||||
"scene.view_settings.exposure": 0.0,
|
||||
"scene.view_settings.gamma": 1.0,
|
||||
"scene.view_settings.look": "None",
|
||||
"scene.view_settings.use_curve_mapping": false,
|
||||
"scene.view_settings.view_transform": "Standard",
|
||||
"scene.display.shading.aov_name": "",
|
||||
"scene.display.shading.background_color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"scene.display.shading.background_type": "THEME",
|
||||
"scene.display.shading.cavity_ridge_factor": 1.0,
|
||||
"scene.display.shading.cavity_type": "BOTH",
|
||||
"scene.display.shading.cavity_valley_factor": 1.0,
|
||||
"scene.display.shading.color_type": "SINGLE",
|
||||
"scene.display.shading.curvature_ridge_factor": 1.0,
|
||||
"scene.display.shading.curvature_valley_factor": 1.0,
|
||||
"scene.display.shading.light": "FLAT",
|
||||
"scene.display.shading.object_outline_color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"scene.display.shading.render_pass": "COMBINED",
|
||||
"scene.display.shading.shadow_intensity": 0.5,
|
||||
"scene.display.shading.show_backface_culling": false,
|
||||
"scene.display.shading.show_cavity": false,
|
||||
"scene.display.shading.show_object_outline": true,
|
||||
"scene.display.shading.show_shadows": false,
|
||||
"scene.display.shading.show_specular_highlight": true,
|
||||
"scene.display.shading.show_xray": false,
|
||||
"scene.display.shading.show_xray_wireframe": false,
|
||||
"scene.display.shading.single_color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"scene.display.shading.studio_light": "Default",
|
||||
"scene.display.shading.studiolight_background_alpha": 0.0,
|
||||
"scene.display.shading.studiolight_background_blur": 0.0,
|
||||
"scene.display.shading.studiolight_intensity": 0.0,
|
||||
"scene.display.shading.studiolight_rotate_z": 0.0,
|
||||
"scene.display.shading.type": "SOLID",
|
||||
"scene.display.shading.use_compositor": "DISABLED",
|
||||
"scene.display.shading.use_dof": false,
|
||||
"scene.display.shading.use_scene_lights": false,
|
||||
"scene.display.shading.use_scene_lights_render": false,
|
||||
"scene.display.shading.use_scene_world": false,
|
||||
"scene.display.shading.use_scene_world_render": false,
|
||||
"scene.display.shading.use_studiolight_view_rotation": true,
|
||||
"scene.display.shading.use_world_space_lighting": false,
|
||||
"scene.display.shading.wireframe_color_type": "MATERIAL",
|
||||
"scene.display.shading.xray_alpha": 0.5,
|
||||
"scene.display.shading.xray_alpha_wireframe": 0.0,
|
||||
"scene.display.light_direction": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"scene.display.matcap_ssao_attenuation": 1.0,
|
||||
"scene.display.matcap_ssao_distance": 0.20000000298023224,
|
||||
"scene.display.matcap_ssao_samples": 16,
|
||||
"scene.display.render_aa": "8",
|
||||
"scene.display.shadow_focus": 0.0,
|
||||
"scene.display.shadow_shift": 0.10000000149011612,
|
||||
"scene.display.viewport_aa": "FXAA",
|
||||
"space.overlay.backwire_opacity": 0.5,
|
||||
"space.overlay.bone_wire_alpha": 1.0,
|
||||
"space.overlay.display_handle": "SELECTED",
|
||||
"space.overlay.fade_inactive_alpha": 0.4000000059604645,
|
||||
"space.overlay.gpencil_fade_layer": 0.5,
|
||||
"space.overlay.gpencil_fade_objects": 0.5,
|
||||
"space.overlay.gpencil_grid_opacity": 0.5,
|
||||
"space.overlay.gpencil_vertex_paint_opacity": 1.0,
|
||||
"space.overlay.grid_lines": 16,
|
||||
"space.overlay.grid_scale": 1.0,
|
||||
"space.overlay.grid_subdivisions": 10,
|
||||
"space.overlay.normals_constant_screen_size": 7.0,
|
||||
"space.overlay.normals_length": 0.10000000149011612,
|
||||
"space.overlay.sculpt_curves_cage_opacity": 0.5,
|
||||
"space.overlay.sculpt_mode_face_sets_opacity": 1.0,
|
||||
"space.overlay.sculpt_mode_mask_opacity": 0.75,
|
||||
"space.overlay.show_annotation": true,
|
||||
"space.overlay.show_axis_x": false,
|
||||
"space.overlay.show_axis_y": false,
|
||||
"space.overlay.show_axis_z": false,
|
||||
"space.overlay.show_bones": true,
|
||||
"space.overlay.show_cursor": true,
|
||||
"space.overlay.show_curve_normals": false,
|
||||
"space.overlay.show_edge_bevel_weight": true,
|
||||
"space.overlay.show_edge_crease": true,
|
||||
"space.overlay.show_edge_seams": true,
|
||||
"space.overlay.show_edge_sharp": true,
|
||||
"space.overlay.show_edges": false,
|
||||
"space.overlay.show_extra_edge_angle": false,
|
||||
"space.overlay.show_extra_edge_length": false,
|
||||
"space.overlay.show_extra_face_angle": false,
|
||||
"space.overlay.show_extra_face_area": false,
|
||||
"space.overlay.show_extra_indices": false,
|
||||
"space.overlay.show_extras": true,
|
||||
"space.overlay.show_face_center": false,
|
||||
"space.overlay.show_face_normals": false,
|
||||
"space.overlay.show_face_orientation": false,
|
||||
"space.overlay.show_faces": true,
|
||||
"space.overlay.show_fade_inactive": false,
|
||||
"space.overlay.show_floor": false,
|
||||
"space.overlay.show_freestyle_edge_marks": true,
|
||||
"space.overlay.show_freestyle_face_marks": true,
|
||||
"space.overlay.show_look_dev": false,
|
||||
"space.overlay.show_motion_paths": true,
|
||||
"space.overlay.show_object_origins": false,
|
||||
"space.overlay.show_object_origins_all": false,
|
||||
"space.overlay.show_occlude_wire": false,
|
||||
"space.overlay.show_onion_skins": false,
|
||||
"space.overlay.show_ortho_grid": true,
|
||||
"space.overlay.show_outline_selected": true,
|
||||
"space.overlay.show_overlays": true,
|
||||
"space.overlay.show_paint_wire": false,
|
||||
"space.overlay.show_relationship_lines": false,
|
||||
"space.overlay.show_sculpt_curves_cage": true,
|
||||
"space.overlay.show_sculpt_face_sets": true,
|
||||
"space.overlay.show_sculpt_mask": true,
|
||||
"space.overlay.show_split_normals": false,
|
||||
"space.overlay.show_stats": false,
|
||||
"space.overlay.show_statvis": false,
|
||||
"space.overlay.show_text": true,
|
||||
"space.overlay.show_vertex_normals": false,
|
||||
"space.overlay.show_viewer_attribute": true,
|
||||
"space.overlay.show_weight": false,
|
||||
"space.overlay.show_wireframes": true,
|
||||
"space.overlay.show_wpaint_contours": false,
|
||||
"space.overlay.show_xray_bone": false,
|
||||
"space.overlay.texture_paint_mode_opacity": 1.0,
|
||||
"space.overlay.use_debug_freeze_view_culling": false,
|
||||
"space.overlay.use_gpencil_canvas_xray": false,
|
||||
"space.overlay.use_gpencil_edit_lines": true,
|
||||
"space.overlay.use_gpencil_fade_gp_objects": false,
|
||||
"space.overlay.use_gpencil_fade_layers": false,
|
||||
"space.overlay.use_gpencil_fade_objects": false,
|
||||
"space.overlay.use_gpencil_grid": false,
|
||||
"space.overlay.use_gpencil_multiedit_line_only": false,
|
||||
"space.overlay.use_gpencil_onion_skin": false,
|
||||
"space.overlay.use_gpencil_show_directions": false,
|
||||
"space.overlay.use_gpencil_show_material_name": false,
|
||||
"space.overlay.use_normals_constant_screen_size": false,
|
||||
"space.overlay.vertex_opacity": 1.0,
|
||||
"space.overlay.vertex_paint_mode_opacity": 1.0,
|
||||
"space.overlay.viewer_attribute_opacity": 1.0,
|
||||
"space.overlay.weight_paint_mode_opacity": 1.0,
|
||||
"space.overlay.wireframe_opacity": 1.0,
|
||||
"space.overlay.wireframe_threshold": 0.0,
|
||||
"space.overlay.xray_alpha_bone": 0.0
|
||||
}
|
||||
},
|
||||
"Shaded": {
|
||||
"render_type": "VIEWPORT",
|
||||
"raster_style": {
|
||||
"bpy.data.worlds[0].color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"scene.render.bake_bias": 0.0010000000474974513,
|
||||
"scene.render.bake_margin": 16,
|
||||
"scene.render.bake_margin_type": "ADJACENT_FACES",
|
||||
"scene.render.bake_samples": 256,
|
||||
"scene.render.bake_type": "NORMALS",
|
||||
"scene.render.bake_user_scale": 0.0,
|
||||
"scene.render.border_max_x": 1.0,
|
||||
"scene.render.border_max_y": 1.0,
|
||||
"scene.render.border_min_x": 0.0,
|
||||
"scene.render.border_min_y": 0.0,
|
||||
"scene.render.dither_intensity": 1.0,
|
||||
"scene.render.engine": "BLENDER_WORKBENCH",
|
||||
"scene.render.film_transparent": false,
|
||||
"scene.render.filter_size": 1.5,
|
||||
"scene.render.fps": 24,
|
||||
"scene.render.fps_base": 1.0,
|
||||
"scene.render.frame_map_new": 100,
|
||||
"scene.render.frame_map_old": 100,
|
||||
"scene.render.hair_subdiv": 0,
|
||||
"scene.render.hair_type": "STRAND",
|
||||
"scene.render.line_thickness": 1.0,
|
||||
"scene.render.line_thickness_mode": "ABSOLUTE",
|
||||
"scene.render.metadata_input": "SCENE",
|
||||
"scene.render.motion_blur_shutter": 0.5,
|
||||
"scene.render.pixel_aspect_x": 1.0,
|
||||
"scene.render.pixel_aspect_y": 1.0,
|
||||
"scene.render.preview_pixel_size": "AUTO",
|
||||
"scene.render.resolution_percentage": 100,
|
||||
"scene.render.resolution_x": 1000,
|
||||
"scene.render.resolution_y": 1000,
|
||||
"scene.render.sequencer_gl_preview": "SOLID",
|
||||
"scene.render.simplify_child_particles": 1.0,
|
||||
"scene.render.simplify_child_particles_render": 1.0,
|
||||
"scene.render.simplify_gpencil": false,
|
||||
"scene.render.simplify_gpencil_antialiasing": true,
|
||||
"scene.render.simplify_gpencil_modifier": true,
|
||||
"scene.render.simplify_gpencil_onplay": false,
|
||||
"scene.render.simplify_gpencil_shader_fx": true,
|
||||
"scene.render.simplify_gpencil_tint": true,
|
||||
"scene.render.simplify_gpencil_view_fill": true,
|
||||
"scene.render.simplify_shadows": 1.0,
|
||||
"scene.render.simplify_shadows_render": 1.0,
|
||||
"scene.render.simplify_subdivision": 6,
|
||||
"scene.render.simplify_subdivision_render": 6,
|
||||
"scene.render.simplify_volumes": 1.0,
|
||||
"scene.render.stamp_font_size": 12,
|
||||
"scene.render.stamp_note_text": "",
|
||||
"scene.render.threads": 20,
|
||||
"scene.render.threads_mode": "AUTO",
|
||||
"scene.render.use_bake_clear": true,
|
||||
"scene.render.use_bake_lores_mesh": false,
|
||||
"scene.render.use_bake_multires": false,
|
||||
"scene.render.use_bake_selected_to_active": false,
|
||||
"scene.render.use_bake_user_scale": false,
|
||||
"scene.render.use_border": false,
|
||||
"scene.render.use_compositing": true,
|
||||
"scene.render.use_crop_to_border": false,
|
||||
"scene.render.use_file_extension": true,
|
||||
"scene.render.use_freestyle": false,
|
||||
"scene.render.use_high_quality_normals": false,
|
||||
"scene.render.use_lock_interface": false,
|
||||
"scene.render.use_motion_blur": false,
|
||||
"scene.render.use_multiview": false,
|
||||
"scene.render.use_overwrite": true,
|
||||
"scene.render.use_persistent_data": false,
|
||||
"scene.render.use_placeholder": false,
|
||||
"scene.render.use_render_cache": false,
|
||||
"scene.render.use_sequencer": true,
|
||||
"scene.render.use_sequencer_override_scene_strip": false,
|
||||
"scene.render.use_simplify": false,
|
||||
"scene.render.use_single_layer": false,
|
||||
"scene.render.use_stamp": false,
|
||||
"scene.render.use_stamp_camera": true,
|
||||
"scene.render.use_stamp_date": true,
|
||||
"scene.render.use_stamp_filename": true,
|
||||
"scene.render.use_stamp_frame": true,
|
||||
"scene.render.use_stamp_frame_range": false,
|
||||
"scene.render.use_stamp_hostname": false,
|
||||
"scene.render.use_stamp_labels": true,
|
||||
"scene.render.use_stamp_lens": false,
|
||||
"scene.render.use_stamp_marker": false,
|
||||
"scene.render.use_stamp_memory": false,
|
||||
"scene.render.use_stamp_note": false,
|
||||
"scene.render.use_stamp_render_time": true,
|
||||
"scene.render.use_stamp_scene": true,
|
||||
"scene.render.use_stamp_sequencer_strip": false,
|
||||
"scene.render.use_stamp_time": true,
|
||||
"scene.render.views_format": "STEREO_3D",
|
||||
"scene.view_settings.exposure": 0.0,
|
||||
"scene.view_settings.gamma": 1.0,
|
||||
"scene.view_settings.look": "None",
|
||||
"scene.view_settings.use_curve_mapping": false,
|
||||
"scene.view_settings.view_transform": "Standard",
|
||||
"scene.display.shading.aov_name": "",
|
||||
"scene.display.shading.background_color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"scene.display.shading.background_type": "THEME",
|
||||
"scene.display.shading.cavity_ridge_factor": 1.0,
|
||||
"scene.display.shading.cavity_type": "BOTH",
|
||||
"scene.display.shading.cavity_valley_factor": 1.0,
|
||||
"scene.display.shading.color_type": "MATERIAL",
|
||||
"scene.display.shading.curvature_ridge_factor": 1.0,
|
||||
"scene.display.shading.curvature_valley_factor": 1.0,
|
||||
"scene.display.shading.light": "STUDIO",
|
||||
"scene.display.shading.object_outline_color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"scene.display.shading.render_pass": "COMBINED",
|
||||
"scene.display.shading.shadow_intensity": 0.5,
|
||||
"scene.display.shading.show_backface_culling": false,
|
||||
"scene.display.shading.show_cavity": true,
|
||||
"scene.display.shading.show_object_outline": true,
|
||||
"scene.display.shading.show_shadows": true,
|
||||
"scene.display.shading.show_specular_highlight": true,
|
||||
"scene.display.shading.show_xray": false,
|
||||
"scene.display.shading.show_xray_wireframe": false,
|
||||
"scene.display.shading.single_color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"scene.display.shading.studio_light": "Default",
|
||||
"scene.display.shading.studiolight_background_alpha": 0.0,
|
||||
"scene.display.shading.studiolight_background_blur": 0.0,
|
||||
"scene.display.shading.studiolight_intensity": 0.0,
|
||||
"scene.display.shading.studiolight_rotate_z": 0.0,
|
||||
"scene.display.shading.type": "SOLID",
|
||||
"scene.display.shading.use_compositor": "DISABLED",
|
||||
"scene.display.shading.use_dof": false,
|
||||
"scene.display.shading.use_scene_lights": false,
|
||||
"scene.display.shading.use_scene_lights_render": false,
|
||||
"scene.display.shading.use_scene_world": false,
|
||||
"scene.display.shading.use_scene_world_render": false,
|
||||
"scene.display.shading.use_studiolight_view_rotation": true,
|
||||
"scene.display.shading.use_world_space_lighting": false,
|
||||
"scene.display.shading.wireframe_color_type": "MATERIAL",
|
||||
"scene.display.shading.xray_alpha": 0.5,
|
||||
"scene.display.shading.xray_alpha_wireframe": 0.0,
|
||||
"scene.display.light_direction": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"scene.display.matcap_ssao_attenuation": 1.0,
|
||||
"scene.display.matcap_ssao_distance": 0.20000000298023224,
|
||||
"scene.display.matcap_ssao_samples": 16,
|
||||
"scene.display.render_aa": "8",
|
||||
"scene.display.shadow_focus": 0.0,
|
||||
"scene.display.shadow_shift": 0.10000000149011612,
|
||||
"scene.display.viewport_aa": "FXAA",
|
||||
"space.overlay.backwire_opacity": 0.5,
|
||||
"space.overlay.bone_wire_alpha": 1.0,
|
||||
"space.overlay.display_handle": "SELECTED",
|
||||
"space.overlay.fade_inactive_alpha": 0.4000000059604645,
|
||||
"space.overlay.gpencil_fade_layer": 0.5,
|
||||
"space.overlay.gpencil_fade_objects": 0.5,
|
||||
"space.overlay.gpencil_grid_opacity": 0.5,
|
||||
"space.overlay.gpencil_vertex_paint_opacity": 1.0,
|
||||
"space.overlay.grid_lines": 16,
|
||||
"space.overlay.grid_scale": 1.0,
|
||||
"space.overlay.grid_subdivisions": 10,
|
||||
"space.overlay.normals_constant_screen_size": 7.0,
|
||||
"space.overlay.normals_length": 0.10000000149011612,
|
||||
"space.overlay.sculpt_curves_cage_opacity": 0.5,
|
||||
"space.overlay.sculpt_mode_face_sets_opacity": 1.0,
|
||||
"space.overlay.sculpt_mode_mask_opacity": 0.75,
|
||||
"space.overlay.show_annotation": true,
|
||||
"space.overlay.show_axis_x": false,
|
||||
"space.overlay.show_axis_y": false,
|
||||
"space.overlay.show_axis_z": false,
|
||||
"space.overlay.show_bones": true,
|
||||
"space.overlay.show_cursor": true,
|
||||
"space.overlay.show_curve_normals": false,
|
||||
"space.overlay.show_edge_bevel_weight": true,
|
||||
"space.overlay.show_edge_crease": true,
|
||||
"space.overlay.show_edge_seams": true,
|
||||
"space.overlay.show_edge_sharp": true,
|
||||
"space.overlay.show_edges": false,
|
||||
"space.overlay.show_extra_edge_angle": false,
|
||||
"space.overlay.show_extra_edge_length": false,
|
||||
"space.overlay.show_extra_face_angle": false,
|
||||
"space.overlay.show_extra_face_area": false,
|
||||
"space.overlay.show_extra_indices": false,
|
||||
"space.overlay.show_extras": true,
|
||||
"space.overlay.show_face_center": false,
|
||||
"space.overlay.show_face_normals": false,
|
||||
"space.overlay.show_face_orientation": false,
|
||||
"space.overlay.show_faces": true,
|
||||
"space.overlay.show_fade_inactive": false,
|
||||
"space.overlay.show_floor": false,
|
||||
"space.overlay.show_freestyle_edge_marks": true,
|
||||
"space.overlay.show_freestyle_face_marks": true,
|
||||
"space.overlay.show_look_dev": false,
|
||||
"space.overlay.show_motion_paths": true,
|
||||
"space.overlay.show_object_origins": false,
|
||||
"space.overlay.show_object_origins_all": false,
|
||||
"space.overlay.show_occlude_wire": false,
|
||||
"space.overlay.show_onion_skins": false,
|
||||
"space.overlay.show_ortho_grid": true,
|
||||
"space.overlay.show_outline_selected": true,
|
||||
"space.overlay.show_overlays": true,
|
||||
"space.overlay.show_paint_wire": false,
|
||||
"space.overlay.show_relationship_lines": false,
|
||||
"space.overlay.show_sculpt_curves_cage": true,
|
||||
"space.overlay.show_sculpt_face_sets": true,
|
||||
"space.overlay.show_sculpt_mask": true,
|
||||
"space.overlay.show_split_normals": false,
|
||||
"space.overlay.show_stats": false,
|
||||
"space.overlay.show_statvis": false,
|
||||
"space.overlay.show_text": true,
|
||||
"space.overlay.show_vertex_normals": false,
|
||||
"space.overlay.show_viewer_attribute": true,
|
||||
"space.overlay.show_weight": false,
|
||||
"space.overlay.show_wireframes": false,
|
||||
"space.overlay.show_wpaint_contours": false,
|
||||
"space.overlay.show_xray_bone": false,
|
||||
"space.overlay.texture_paint_mode_opacity": 1.0,
|
||||
"space.overlay.use_debug_freeze_view_culling": false,
|
||||
"space.overlay.use_gpencil_canvas_xray": false,
|
||||
"space.overlay.use_gpencil_edit_lines": true,
|
||||
"space.overlay.use_gpencil_fade_gp_objects": false,
|
||||
"space.overlay.use_gpencil_fade_layers": false,
|
||||
"space.overlay.use_gpencil_fade_objects": false,
|
||||
"space.overlay.use_gpencil_grid": false,
|
||||
"space.overlay.use_gpencil_multiedit_line_only": false,
|
||||
"space.overlay.use_gpencil_onion_skin": false,
|
||||
"space.overlay.use_gpencil_show_directions": false,
|
||||
"space.overlay.use_gpencil_show_material_name": false,
|
||||
"space.overlay.use_normals_constant_screen_size": false,
|
||||
"space.overlay.vertex_opacity": 1.0,
|
||||
"space.overlay.vertex_paint_mode_opacity": 1.0,
|
||||
"space.overlay.viewer_attribute_opacity": 1.0,
|
||||
"space.overlay.weight_paint_mode_opacity": 1.0,
|
||||
"space.overlay.wireframe_opacity": 1.0,
|
||||
"space.overlay.wireframe_threshold": 0.0,
|
||||
"space.overlay.xray_alpha_bone": 0.0
|
||||
}
|
||||
},
|
||||
"Blender Default": {
|
||||
"render_type": "VIEWPORT",
|
||||
"raster_style": {
|
||||
"bpy.data.worlds[0].color": [
|
||||
0.05087608844041824,
|
||||
0.05087608844041824,
|
||||
0.05087608844041824
|
||||
],
|
||||
"scene.render.bake_bias": 0.0010000000474974513,
|
||||
"scene.render.bake_margin": 16,
|
||||
"scene.render.bake_margin_type": "ADJACENT_FACES",
|
||||
"scene.render.bake_samples": 256,
|
||||
"scene.render.bake_type": "NORMALS",
|
||||
"scene.render.bake_user_scale": 0.0,
|
||||
"scene.render.border_max_x": 1.0,
|
||||
"scene.render.border_max_y": 1.0,
|
||||
"scene.render.border_min_x": 0.0,
|
||||
"scene.render.border_min_y": 0.0,
|
||||
"scene.render.dither_intensity": 1.0,
|
||||
"scene.render.engine": "BLENDER_EEVEE",
|
||||
"scene.render.film_transparent": false,
|
||||
"scene.render.filter_size": 1.5,
|
||||
"scene.render.fps": 24,
|
||||
"scene.render.fps_base": 1.0,
|
||||
"scene.render.frame_map_new": 100,
|
||||
"scene.render.frame_map_old": 100,
|
||||
"scene.render.hair_subdiv": 0,
|
||||
"scene.render.hair_type": "STRAND",
|
||||
"scene.render.line_thickness": 1.0,
|
||||
"scene.render.line_thickness_mode": "ABSOLUTE",
|
||||
"scene.render.metadata_input": "SCENE",
|
||||
"scene.render.motion_blur_shutter": 0.5,
|
||||
"scene.render.pixel_aspect_x": 1.0,
|
||||
"scene.render.pixel_aspect_y": 1.0,
|
||||
"scene.render.preview_pixel_size": "AUTO",
|
||||
"scene.render.resolution_percentage": 100,
|
||||
"scene.render.resolution_x": 1000,
|
||||
"scene.render.resolution_y": 1000,
|
||||
"scene.render.sequencer_gl_preview": "SOLID",
|
||||
"scene.render.simplify_child_particles": 1.0,
|
||||
"scene.render.simplify_child_particles_render": 1.0,
|
||||
"scene.render.simplify_gpencil": false,
|
||||
"scene.render.simplify_gpencil_antialiasing": true,
|
||||
"scene.render.simplify_gpencil_modifier": true,
|
||||
"scene.render.simplify_gpencil_onplay": false,
|
||||
"scene.render.simplify_gpencil_shader_fx": true,
|
||||
"scene.render.simplify_gpencil_tint": true,
|
||||
"scene.render.simplify_gpencil_view_fill": true,
|
||||
"scene.render.simplify_shadows": 1.0,
|
||||
"scene.render.simplify_shadows_render": 1.0,
|
||||
"scene.render.simplify_subdivision": 6,
|
||||
"scene.render.simplify_subdivision_render": 6,
|
||||
"scene.render.simplify_volumes": 1.0,
|
||||
"scene.render.stamp_font_size": 12,
|
||||
"scene.render.stamp_note_text": "",
|
||||
"scene.render.threads": 20,
|
||||
"scene.render.threads_mode": "AUTO",
|
||||
"scene.render.use_bake_clear": true,
|
||||
"scene.render.use_bake_lores_mesh": false,
|
||||
"scene.render.use_bake_multires": false,
|
||||
"scene.render.use_bake_selected_to_active": false,
|
||||
"scene.render.use_bake_user_scale": false,
|
||||
"scene.render.use_border": false,
|
||||
"scene.render.use_compositing": true,
|
||||
"scene.render.use_crop_to_border": false,
|
||||
"scene.render.use_file_extension": true,
|
||||
"scene.render.use_freestyle": false,
|
||||
"scene.render.use_high_quality_normals": false,
|
||||
"scene.render.use_lock_interface": false,
|
||||
"scene.render.use_motion_blur": false,
|
||||
"scene.render.use_multiview": false,
|
||||
"scene.render.use_overwrite": true,
|
||||
"scene.render.use_persistent_data": false,
|
||||
"scene.render.use_placeholder": false,
|
||||
"scene.render.use_render_cache": false,
|
||||
"scene.render.use_sequencer": true,
|
||||
"scene.render.use_sequencer_override_scene_strip": false,
|
||||
"scene.render.use_simplify": false,
|
||||
"scene.render.use_single_layer": false,
|
||||
"scene.render.use_stamp": false,
|
||||
"scene.render.use_stamp_camera": true,
|
||||
"scene.render.use_stamp_date": true,
|
||||
"scene.render.use_stamp_filename": true,
|
||||
"scene.render.use_stamp_frame": true,
|
||||
"scene.render.use_stamp_frame_range": false,
|
||||
"scene.render.use_stamp_hostname": false,
|
||||
"scene.render.use_stamp_labels": true,
|
||||
"scene.render.use_stamp_lens": false,
|
||||
"scene.render.use_stamp_marker": false,
|
||||
"scene.render.use_stamp_memory": false,
|
||||
"scene.render.use_stamp_note": false,
|
||||
"scene.render.use_stamp_render_time": true,
|
||||
"scene.render.use_stamp_scene": true,
|
||||
"scene.render.use_stamp_sequencer_strip": false,
|
||||
"scene.render.use_stamp_time": true,
|
||||
"scene.render.views_format": "STEREO_3D",
|
||||
"scene.view_settings.exposure": 0.0,
|
||||
"scene.view_settings.gamma": 1.0,
|
||||
"scene.view_settings.look": "None",
|
||||
"scene.view_settings.use_curve_mapping": false,
|
||||
"scene.view_settings.view_transform": "Filmic",
|
||||
"scene.display.shading.aov_name": "",
|
||||
"scene.display.shading.background_color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"scene.display.shading.background_type": "THEME",
|
||||
"scene.display.shading.cavity_ridge_factor": 1.0,
|
||||
"scene.display.shading.cavity_type": "WORLD",
|
||||
"scene.display.shading.cavity_valley_factor": 1.0,
|
||||
"scene.display.shading.color_type": "MATERIAL",
|
||||
"scene.display.shading.curvature_ridge_factor": 0.0,
|
||||
"scene.display.shading.curvature_valley_factor": 0.0,
|
||||
"scene.display.shading.light": "STUDIO",
|
||||
"scene.display.shading.object_outline_color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"scene.display.shading.render_pass": "COMBINED",
|
||||
"scene.display.shading.shadow_intensity": 0.5,
|
||||
"scene.display.shading.show_backface_culling": false,
|
||||
"scene.display.shading.show_cavity": false,
|
||||
"scene.display.shading.show_object_outline": false,
|
||||
"scene.display.shading.show_shadows": false,
|
||||
"scene.display.shading.show_specular_highlight": true,
|
||||
"scene.display.shading.show_xray": false,
|
||||
"scene.display.shading.show_xray_wireframe": false,
|
||||
"scene.display.shading.single_color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929
|
||||
],
|
||||
"scene.display.shading.studio_light": "Default",
|
||||
"scene.display.shading.studiolight_background_alpha": 0.0,
|
||||
"scene.display.shading.studiolight_background_blur": 0.0,
|
||||
"scene.display.shading.studiolight_intensity": 0.0,
|
||||
"scene.display.shading.studiolight_rotate_z": 0.0,
|
||||
"scene.display.shading.type": "SOLID",
|
||||
"scene.display.shading.use_compositor": "DISABLED",
|
||||
"scene.display.shading.use_dof": false,
|
||||
"scene.display.shading.use_scene_lights": false,
|
||||
"scene.display.shading.use_scene_lights_render": false,
|
||||
"scene.display.shading.use_scene_world": false,
|
||||
"scene.display.shading.use_scene_world_render": false,
|
||||
"scene.display.shading.use_studiolight_view_rotation": true,
|
||||
"scene.display.shading.use_world_space_lighting": false,
|
||||
"scene.display.shading.wireframe_color_type": "MATERIAL",
|
||||
"scene.display.shading.xray_alpha": 0.5,
|
||||
"scene.display.shading.xray_alpha_wireframe": 0.0,
|
||||
"scene.display.light_direction": [
|
||||
0.5773502588272095,
|
||||
0.5773502588272095,
|
||||
0.5773502588272095
|
||||
],
|
||||
"scene.display.matcap_ssao_attenuation": 1.0,
|
||||
"scene.display.matcap_ssao_distance": 0.20000000298023224,
|
||||
"scene.display.matcap_ssao_samples": 16,
|
||||
"scene.display.render_aa": "8",
|
||||
"scene.display.shadow_focus": 0.0,
|
||||
"scene.display.shadow_shift": 0.10000000149011612,
|
||||
"scene.display.viewport_aa": "FXAA",
|
||||
"space.overlay.backwire_opacity": 0.5,
|
||||
"space.overlay.bone_wire_alpha": 1.0,
|
||||
"space.overlay.display_handle": "SELECTED",
|
||||
"space.overlay.fade_inactive_alpha": 0.4000000059604645,
|
||||
"space.overlay.gpencil_fade_layer": 0.5,
|
||||
"space.overlay.gpencil_fade_objects": 0.5,
|
||||
"space.overlay.gpencil_grid_opacity": 0.5,
|
||||
"space.overlay.gpencil_vertex_paint_opacity": 1.0,
|
||||
"space.overlay.grid_lines": 16,
|
||||
"space.overlay.grid_scale": 1.0,
|
||||
"space.overlay.grid_subdivisions": 10,
|
||||
"space.overlay.normals_constant_screen_size": 7.0,
|
||||
"space.overlay.normals_length": 0.10000000149011612,
|
||||
"space.overlay.sculpt_curves_cage_opacity": 0.5,
|
||||
"space.overlay.sculpt_mode_face_sets_opacity": 1.0,
|
||||
"space.overlay.sculpt_mode_mask_opacity": 0.75,
|
||||
"space.overlay.show_annotation": true,
|
||||
"space.overlay.show_axis_x": true,
|
||||
"space.overlay.show_axis_y": true,
|
||||
"space.overlay.show_axis_z": false,
|
||||
"space.overlay.show_bones": true,
|
||||
"space.overlay.show_cursor": true,
|
||||
"space.overlay.show_curve_normals": false,
|
||||
"space.overlay.show_edge_bevel_weight": true,
|
||||
"space.overlay.show_edge_crease": true,
|
||||
"space.overlay.show_edge_seams": true,
|
||||
"space.overlay.show_edge_sharp": true,
|
||||
"space.overlay.show_edges": false,
|
||||
"space.overlay.show_extra_edge_angle": false,
|
||||
"space.overlay.show_extra_edge_length": false,
|
||||
"space.overlay.show_extra_face_angle": false,
|
||||
"space.overlay.show_extra_face_area": false,
|
||||
"space.overlay.show_extra_indices": false,
|
||||
"space.overlay.show_extras": true,
|
||||
"space.overlay.show_face_center": false,
|
||||
"space.overlay.show_face_normals": false,
|
||||
"space.overlay.show_face_orientation": false,
|
||||
"space.overlay.show_faces": true,
|
||||
"space.overlay.show_fade_inactive": false,
|
||||
"space.overlay.show_floor": true,
|
||||
"space.overlay.show_freestyle_edge_marks": true,
|
||||
"space.overlay.show_freestyle_face_marks": true,
|
||||
"space.overlay.show_look_dev": false,
|
||||
"space.overlay.show_motion_paths": true,
|
||||
"space.overlay.show_object_origins": true,
|
||||
"space.overlay.show_object_origins_all": false,
|
||||
"space.overlay.show_occlude_wire": false,
|
||||
"space.overlay.show_onion_skins": false,
|
||||
"space.overlay.show_ortho_grid": true,
|
||||
"space.overlay.show_outline_selected": true,
|
||||
"space.overlay.show_overlays": true,
|
||||
"space.overlay.show_paint_wire": false,
|
||||
"space.overlay.show_relationship_lines": true,
|
||||
"space.overlay.show_sculpt_curves_cage": true,
|
||||
"space.overlay.show_sculpt_face_sets": true,
|
||||
"space.overlay.show_sculpt_mask": true,
|
||||
"space.overlay.show_split_normals": false,
|
||||
"space.overlay.show_stats": false,
|
||||
"space.overlay.show_statvis": false,
|
||||
"space.overlay.show_text": true,
|
||||
"space.overlay.show_vertex_normals": false,
|
||||
"space.overlay.show_viewer_attribute": true,
|
||||
"space.overlay.show_weight": false,
|
||||
"space.overlay.show_wireframes": false,
|
||||
"space.overlay.show_wpaint_contours": false,
|
||||
"space.overlay.show_xray_bone": false,
|
||||
"space.overlay.texture_paint_mode_opacity": 1.0,
|
||||
"space.overlay.use_debug_freeze_view_culling": false,
|
||||
"space.overlay.use_gpencil_canvas_xray": false,
|
||||
"space.overlay.use_gpencil_edit_lines": true,
|
||||
"space.overlay.use_gpencil_fade_gp_objects": false,
|
||||
"space.overlay.use_gpencil_fade_layers": false,
|
||||
"space.overlay.use_gpencil_fade_objects": false,
|
||||
"space.overlay.use_gpencil_grid": false,
|
||||
"space.overlay.use_gpencil_multiedit_line_only": false,
|
||||
"space.overlay.use_gpencil_onion_skin": false,
|
||||
"space.overlay.use_gpencil_show_directions": false,
|
||||
"space.overlay.use_gpencil_show_material_name": false,
|
||||
"space.overlay.use_normals_constant_screen_size": false,
|
||||
"space.overlay.vertex_opacity": 1.0,
|
||||
"space.overlay.vertex_paint_mode_opacity": 1.0,
|
||||
"space.overlay.viewer_attribute_opacity": 1.0,
|
||||
"space.overlay.weight_paint_mode_opacity": 1.0,
|
||||
"space.overlay.wireframe_opacity": 1.0,
|
||||
"space.overlay.wireframe_threshold": 1.0,
|
||||
"space.overlay.xray_alpha_bone": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<svg baseProfile="full" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="rectangle-tag">
|
||||
<rect x="-6" y="-2.5" width="12" height="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
</g>
|
||||
<g id="triangle-tag">
|
||||
<path style="fill: white; stroke: black; stroke-width: 0.25;" d="M 3.1409425e-7,-7.1069207 5.7650623,2.8784603 l -11.5301246,-6e-7 z" />
|
||||
</g>
|
||||
<g id="hexagon-tag">
|
||||
<path style="fill: white; stroke: black; stroke-width: 0.25;" d="m 0.0161133,-6.0583333 5.2339915,3.8366023 -2.031433,6.1633977 c 0,0 -6.4894866,-0.027414 -6.4894866,-0.027414 l -1.97929,-6.1803395 5.2662181,-3.7922467" />
|
||||
</g>
|
||||
<g id="capsule-tag">
|
||||
<rect x="-6" y="-2.5" width="12" height="5" rx="2.5" ry="2.5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
</g>
|
||||
<g id="circle-tag">
|
||||
<circle r="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
</g>
|
||||
<g id="door-tag">
|
||||
<circle r="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
<text y="-1.75" class="regular" text-anchor="middle" dominant-baseline="middle" data-type="text-template"></text>
|
||||
<line x1="-5" x2="5" style="stroke: black; stroke-width: 0.25;" />
|
||||
<text y="2.5" class="regular" text-anchor="middle" dominant-baseline="middle" data-type="text-template"></text>
|
||||
</g>
|
||||
<g id="space-tag">
|
||||
<text y="-5" class="large" text-anchor="middle" dominant-baseline="middle" data-type="text-template"></text>
|
||||
<rect x="-6" y="-2.5" width="12" height="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
<text class="regular" text-anchor="middle" dominant-baseline="middle" data-type="text-template"></text>
|
||||
<text y="5" class="regular" text-anchor="middle" dominant-baseline="middle" data-type="text-template"></text>
|
||||
</g>
|
||||
<g id="elevation-arrow">
|
||||
<path style="fill: black;" d="M -7.07106 0 0 -7.07106 7.07106 0" />
|
||||
</g>
|
||||
<g id="elevation-tag">
|
||||
<circle r="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
<line x1="-5" y1="0" x2="5" y2="0" style="stroke: black; stroke-width: 0.25;" />
|
||||
</g>
|
||||
<g id="section-arrow">
|
||||
<path style="fill: black;" d="M -7.07106 0 0 -7.07106 7.07106 0" />
|
||||
</g>
|
||||
<g id="section-tag">
|
||||
<circle r="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
<line x1="-5" y1="0" x2="5" y2="0" style="stroke: black; stroke-width: 0.25;" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
@@ -1,67 +1,55 @@
|
||||
<link href="jsgantt.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="../../module/sequence/gantt/main.css" rel="stylesheet" type="text/css"/>
|
||||
<script src="jsgantt.js" type="text/javascript"></script>
|
||||
<style>
|
||||
.gtaskcellwkend,
|
||||
.gtaskcellcurrent,
|
||||
.gminorheadingwkend {
|
||||
background-color: #e1e1e1;
|
||||
}
|
||||
|
||||
.gitemhighlight td {
|
||||
background-color: #ffdaaa;
|
||||
}
|
||||
|
||||
.gtaskblue {
|
||||
background: #4281A4;
|
||||
}
|
||||
|
||||
.gtaskred {
|
||||
background: #C1666B;
|
||||
}
|
||||
|
||||
.gtaskgreen {
|
||||
background: #48A9A6;
|
||||
}
|
||||
|
||||
.gtaskyellow {
|
||||
background: #D4B483;
|
||||
}
|
||||
|
||||
.gmainleft {
|
||||
overflow: visible;
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
<a href="#print" id="print">Print Mode</a>
|
||||
<div style="position:relative" class="gantt" id="GanttChartDIV"></div>
|
||||
<script type="text/javascript">
|
||||
var g = new JSGantt.GanttChart(document.getElementById('GanttChartDIV'), 'day');
|
||||
g.setOptions({
|
||||
vCaptionType: 'Caption', // Set to Show Caption : None,Caption,Resource,Duration,Complete,
|
||||
vQuarterColWidth: 36,
|
||||
vDateTaskDisplayFormat: 'day dd month yyyy', // Shown in tool tip box
|
||||
vDayMajorDateDisplayFormat: 'mon yyyy - Week ww',// Set format to dates in the "Major" header of the "Day" view
|
||||
vWeekMinorDateDisplayFormat: 'dd mon', // Set format to display dates in the "Minor" header of the "Week" view
|
||||
vLang: 'en',
|
||||
vShowTaskInfoLink: 1, // Show link in tool tip (0/1)
|
||||
vShowEndWeekDate: 0, // Show/Hide the date for the last day of the week in header for daily
|
||||
vUseSingleCell: 10000, // Set the threshold cell per table row (Helps performance for large data.
|
||||
vFormatArr: ['Day', 'Week', 'Month', 'Quarter'], // Even with setUseSingleCell using Hour format on such a large chart can cause issues in some browsers,
|
||||
vShowRes: false, // Disable the resource column.
|
||||
vShowComp: false, // Disable the completion column.
|
||||
vShowDur: false, // Disable the duration column, because jsgantt doesn't calculate durations the way we want.
|
||||
vAdditionalHeaders: {ifcduration: {title: 'Duration'}},
|
||||
vUseToolTip: false, // Disable tooltips.
|
||||
vTotalHeight: 900,
|
||||
});
|
||||
document.getElementById('print').addEventListener('click', function() {
|
||||
g.setTotalHeight("");
|
||||
g.Draw();
|
||||
});
|
||||
var json_data = `
|
||||
{{{json_data}}}
|
||||
`;
|
||||
JSGantt.parseJSONString(json_data, g);
|
||||
g.Draw();
|
||||
<script type="text/javascript" src="../../module/sequence/gantt/index.js"></script>
|
||||
<script>
|
||||
var json_data = `{{{json_data}}}`;
|
||||
</script>
|
||||
|
||||
<div id="options" class="no-print">
|
||||
<h4>Choose a language:
|
||||
<select id="lang" class="sweet_button" onchange="set_language(event)">
|
||||
<option value='cn'>Chinese (cn)</option>
|
||||
<option value='cs'>Czech (cs)</option>
|
||||
<option value='nl'>Dutch (Standard)</option>
|
||||
<option value='en' selected>English (en)</option>
|
||||
<option value='fr'>French (fr)</option>
|
||||
<option value='de'>German (de)</option>
|
||||
<option value='hu'>Hungarian (hu)</option>
|
||||
<option value='id'>Indonesian (id)</option>
|
||||
<option value='it'>Italian (it)</option>
|
||||
<option value='ja'>Japanese (ja)</option>
|
||||
<option value='pt'>Portuguese (pt)</option>
|
||||
<option value='ru'>Russian (ru)</option>
|
||||
<option value='es'>Spanish (es)</option>
|
||||
<option value='sv'>Swedish (sv)</option>
|
||||
<option value='tr'>Turkish (tr)</option>
|
||||
</select>
|
||||
</h4>
|
||||
|
||||
<br>
|
||||
</div>
|
||||
<div class="top-right no-print" id="print_options">
|
||||
<select class="sweet_button" id="print_page_size">
|
||||
<option value="210,297">A4 Portrait</option>
|
||||
<option value="297,210">A4 Landscape</option>
|
||||
<option value="297,420">A3 Portrait</option>
|
||||
<option value="420,297">A3 Landscape</option>
|
||||
<option value="420,594">A2 Portrait</option>
|
||||
<option value="594,420">A2 Landscape</option>
|
||||
<option value="594,841">A1 Portrait</option>
|
||||
<option value="841,594">A1 Landscape</option>
|
||||
<option value="841,1189">A0 Portrait</option>
|
||||
<option value="1189,841">A0 Landscape</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="schedule-data" class="no-print"></div>
|
||||
<div id="schedule-header" style=""></div>
|
||||
<div style="position:relative" class="gantt" id="GanttChartDIV"></div>
|
||||
|
||||
<script>
|
||||
var data = `{{{data}}}`;
|
||||
setupPage(data);
|
||||
create_gantt_chart(json_data)
|
||||
</script>
|
||||
@@ -1,13 +1,13 @@
|
||||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1');
|
||||
FILE_NAME('/dev/null','2022-10-14T18:00:26+11:00',(),(),'IfcOpenShell v0.7.0-dc67287d','IfcOpenShell v0.7.0-dc67287d','Nobody');
|
||||
FILE_NAME('/dev/null','2023-02-04T13:08:05+11:00',(),(),'IfcOpenShell v0.7.0-07ee62eb9','IfcOpenShell v0.7.0-07ee62eb9','Nobody');
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPROJECT('0yOx2IKFL4HAbf$IjzE0Kp',$,'BlenderBIM Demo',$,$,$,$,(#12,#16),#7);
|
||||
#2=IFCPROJECTLIBRARY('2jUXWJsnH2pxWl9Bl3Ljhd',$,'BlenderBIM Demo Library',$,$,$,$,$,$);
|
||||
#3=IFCRELDECLARES('0Rn4fWoen7xB9hskGGEfEy',$,$,$,#1,(#2));
|
||||
#1=IFCPROJECT('3ubSuEuavEPfXTf4v0gmbA',$,'BlenderBIM Demo',$,$,$,$,(#12,#16),#7);
|
||||
#2=IFCPROJECTLIBRARY('1Qq43hq0v3B9Ko7EGW0hJ5',$,'BlenderBIM Demo Library',$,$,$,$,$,$);
|
||||
#3=IFCRELDECLARES('0hU2lTJfX70AKkhyURrbam',$,$,$,#1,(#2));
|
||||
#4=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
|
||||
#5=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
|
||||
#6=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
|
||||
@@ -17,89 +17,89 @@ DATA;
|
||||
#10=IFCDIRECTION((1.,0.,0.));
|
||||
#11=IFCAXIS2PLACEMENT3D(#8,#9,#10);
|
||||
#12=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#11,$);
|
||||
#13=IFCCARTESIANPOINT((0.,0.,0.));
|
||||
#14=IFCDIRECTION((1.,0.,0.));
|
||||
#13=IFCCARTESIANPOINT((0.,0.));
|
||||
#14=IFCDIRECTION((1.,0.));
|
||||
#15=IFCAXIS2PLACEMENT2D(#13,#14);
|
||||
#16=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Plan',2,1.E-05,#15,$);
|
||||
#17=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#12,$,.MODEL_VIEW.,$);
|
||||
#18=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Plan',*,*,*,*,#16,$,.PLAN_VIEW.,$);
|
||||
#18=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Plan',*,*,*,*,#16,$,.PLAN_VIEW.,$);
|
||||
#19=IFCMATERIAL('Unknown',$,$);
|
||||
#20=IFCWALLTYPE('0D2QFqmA18fvA6TUteIRXc',$,'WAL50',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#20=IFCWALLTYPE('3yGmcLQT96CPWJXcV3vNPJ',$,'WAL50',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#21=IFCMATERIALLAYERSET((#23),$,$);
|
||||
#22=IFCRELASSOCIATESMATERIAL('0WbN7alqv8ix3w4MOdyl8F',$,$,$,(#20),#21);
|
||||
#22=IFCRELASSOCIATESMATERIAL('0JMzROKjj7i8EKtMLZ2nXy',$,$,$,(#20),#21);
|
||||
#23=IFCMATERIALLAYER(#19,0.05,$,$,$,$,$);
|
||||
#24=IFCRELDECLARES('13kodoVGr08Bn7WfGWndV_',$,$,$,#2,(#37,#41,#76,#47,#58,#91,#25,#225,#71,#159,#29,#62,#95,#20,#53,#86,#33,#66,#81));
|
||||
#25=IFCWALLTYPE('0qRxb2OqjDEfFI9i7b6qAw',$,'WAL100',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#24=IFCRELDECLARES('1TTgyh7ynBQ8XpgpGSU6ao',$,$,$,#2,(#41,#76,#47,#58,#91,#25,#159,#225,#71,#29,#62,#95,#20,#53,#86,#33,#66,#81,#37));
|
||||
#25=IFCWALLTYPE('20jY5HfLH4LBwMrDEoTdML',$,'WAL100',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#26=IFCMATERIALLAYERSET((#28),$,$);
|
||||
#27=IFCRELASSOCIATESMATERIAL('3BDm6HH553QhwCW7FPmjrR',$,$,$,(#25),#26);
|
||||
#27=IFCRELASSOCIATESMATERIAL('2sICOUhur5WgrNUOi1pvhV',$,$,$,(#25),#26);
|
||||
#28=IFCMATERIALLAYER(#19,0.1,$,$,$,$,$);
|
||||
#29=IFCWALLTYPE('1KMENjmzj7cf_am9SYEaXW',$,'WAL200',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#29=IFCWALLTYPE('0xhGqQenH5Ov9L_CiLywqN',$,'WAL200',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#30=IFCMATERIALLAYERSET((#32),$,$);
|
||||
#31=IFCRELASSOCIATESMATERIAL('1$36L06DrDYx1sZ9tBQ_WE',$,$,$,(#29),#30);
|
||||
#31=IFCRELASSOCIATESMATERIAL('2pOhWSsWT4bQwtduxS8HNJ',$,$,$,(#29),#30);
|
||||
#32=IFCMATERIALLAYER(#19,0.2,$,$,$,$,$);
|
||||
#33=IFCWALLTYPE('2y5Y19etz3rhrt8P45fuGA',$,'WAL300',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#33=IFCWALLTYPE('1HrJFcNVH4XQJIRrEmUD6Z',$,'WAL300',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#34=IFCMATERIALLAYERSET((#36),$,$);
|
||||
#35=IFCRELASSOCIATESMATERIAL('1WSONmheTD9xhiluqtfktr',$,$,$,(#33),#34);
|
||||
#35=IFCRELASSOCIATESMATERIAL('0cAK6yBnXAnO$5LYcU3QQl',$,$,$,(#33),#34);
|
||||
#36=IFCMATERIALLAYER(#19,0.3,$,$,$,$,$);
|
||||
#37=IFCCOVERINGTYPE('1pAuiYopL5hxCATiIPV8QG',$,'COV10',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#37=IFCCOVERINGTYPE('11MVutxgn20fTEibOhUiS8',$,'COV10',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#38=IFCMATERIALLAYERSET((#40),$,$);
|
||||
#39=IFCRELASSOCIATESMATERIAL('0ysRf97LT8fw28mDwt2vop',$,$,$,(#37),#38);
|
||||
#39=IFCRELASSOCIATESMATERIAL('1$dvrpTAn6oPSVqcMtsvmV',$,$,$,(#37),#38);
|
||||
#40=IFCMATERIALLAYER(#19,0.01,$,$,$,$,$);
|
||||
#41=IFCCOVERINGTYPE('00LbT8PQf3XwImYkj_i_$4',$,'COV20',$,$,(#45),$,$,$,.NOTDEFINED.);
|
||||
#41=IFCCOVERINGTYPE('1DWvr7poP3ggxFE7vxOot2',$,'COV20',$,$,(#45),$,$,$,.NOTDEFINED.);
|
||||
#42=IFCMATERIALLAYERSET((#44),$,$);
|
||||
#43=IFCRELASSOCIATESMATERIAL('0Kvr3quG19xw6$528t4NQi',$,$,$,(#41),#42);
|
||||
#43=IFCRELASSOCIATESMATERIAL('2uf2C_54501xFgLlk_jqMG',$,$,$,(#41),#42);
|
||||
#44=IFCMATERIALLAYER(#19,0.02,$,$,$,$,$);
|
||||
#45=IFCPROPERTYSET('1IZqsXecj8NQZcNAIAY48P',$,'EPset_Parametric',$,(#46));
|
||||
#45=IFCPROPERTYSET('0fSGHPSBH9U8H_ph5xpH65',$,'EPset_Parametric',$,(#46));
|
||||
#46=IFCPROPERTYSINGLEVALUE('LayerSetDirection',$,IFCLABEL('AXIS2'),$);
|
||||
#47=IFCCOVERINGTYPE('10YNsLMi9409CbEVFmDkJt',$,'COV30',$,$,(#51),$,$,$,.NOTDEFINED.);
|
||||
#47=IFCCOVERINGTYPE('1ayqDfj8XDxB$G7ZFyRagM',$,'COV30',$,$,(#51),$,$,$,.NOTDEFINED.);
|
||||
#48=IFCMATERIALLAYERSET((#50),$,$);
|
||||
#49=IFCRELASSOCIATESMATERIAL('2jZVWXllT9ugYrdBaIBAnt',$,$,$,(#47),#48);
|
||||
#49=IFCRELASSOCIATESMATERIAL('01vVE$oHTA3BLmh2imRGuu',$,$,$,(#47),#48);
|
||||
#50=IFCMATERIALLAYER(#19,0.03,$,$,$,$,$);
|
||||
#51=IFCPROPERTYSET('2M2_M1eSXFYR8vFE96Ecy1',$,'EPset_Parametric',$,(#52));
|
||||
#51=IFCPROPERTYSET('3v7cOUGgT0qxrxlQkzwSIR',$,'EPset_Parametric',$,(#52));
|
||||
#52=IFCPROPERTYSINGLEVALUE('LayerSetDirection',$,IFCLABEL('AXIS3'),$);
|
||||
#53=IFCRAMPTYPE('09P6PVRiT44vIjup23Olfq',$,'RAM200',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#53=IFCRAMPTYPE('0VEv7VZVnDzxHXC$QE2Crm',$,'RAM200',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#54=IFCMATERIALLAYERSET((#56),$,$);
|
||||
#55=IFCRELASSOCIATESMATERIAL('2Ghy1OMS1FLAOmdzrFp4rp',$,$,$,(#53),#54);
|
||||
#55=IFCRELASSOCIATESMATERIAL('0ToQjR2aLAdgGPuqu6UH1o',$,$,$,(#53),#54);
|
||||
#56=IFCMATERIALLAYER(#19,0.2,$,$,$,$,$);
|
||||
#57=IFCCIRCLEPROFILEDEF(.AREA.,$,$,0.3);
|
||||
#58=IFCPILETYPE('0X0OrCsUnDUPVeAu90N_K$',$,'P1',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#58=IFCPILETYPE('26kmCVC0H4lOhCGn6cCLSQ',$,'P1',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#59=IFCMATERIALPROFILESET($,$,(#61),$);
|
||||
#60=IFCRELASSOCIATESMATERIAL('1FiRvXL$nBkuT8B3FfiGT9',$,$,$,(#58),#59);
|
||||
#60=IFCRELASSOCIATESMATERIAL('2Ev3ucMBPDtwntRLG_4cBU',$,$,$,(#58),#59);
|
||||
#61=IFCMATERIALPROFILE($,$,#19,#57,$,$);
|
||||
#62=IFCSLABTYPE('1helZ086v1o8JD3Ow1eWAy',$,'FLR150',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#62=IFCSLABTYPE('3cLRr85lHDAPjHswaO7574',$,'FLR150',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#63=IFCMATERIALLAYERSET((#65),$,$);
|
||||
#64=IFCRELASSOCIATESMATERIAL('3BbM02xKH6h97dBaMJp$Rr',$,$,$,(#62),#63);
|
||||
#64=IFCRELASSOCIATESMATERIAL('07afdGZLHCFej$qXPfCLn9',$,$,$,(#62),#63);
|
||||
#65=IFCMATERIALLAYER(#19,0.2,$,$,$,$,$);
|
||||
#66=IFCSLABTYPE('1YAagoi$9D_hPiWtssbkcG',$,'FLR250',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#66=IFCSLABTYPE('2WiuelwGf3Ah3gnVgDGEAn',$,'FLR250',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#67=IFCMATERIALLAYERSET((#69),$,$);
|
||||
#68=IFCRELASSOCIATESMATERIAL('0m1oulHjT1u889pxJG$XG_',$,$,$,(#66),#67);
|
||||
#68=IFCRELASSOCIATESMATERIAL('03XoY4bYD4ZwZgvg3JqIIK',$,$,$,(#66),#67);
|
||||
#69=IFCMATERIALLAYER(#19,0.3,$,$,$,$,$);
|
||||
#70=IFCRECTANGLEPROFILEDEF(.AREA.,$,$,0.5,0.6);
|
||||
#71=IFCCOLUMNTYPE('1lzPzyyFfFYRgjqMHnKZLx',$,'C1',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#70=IFCRECTANGLEPROFILEDEF(.AREA.,'500x600',$,0.5,0.6);
|
||||
#71=IFCCOLUMNTYPE('187MdL9O13_OzlwsOaT0zY',$,'C1',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#72=IFCMATERIALPROFILESET($,$,(#74),$);
|
||||
#73=IFCRELASSOCIATESMATERIAL('26fuP2VpfEnhlUsk0K1i4y',$,$,$,(#71),#72);
|
||||
#73=IFCRELASSOCIATESMATERIAL('1CMVTn08P2Tu8afsZHQiUk',$,$,$,(#71),#72);
|
||||
#74=IFCMATERIALPROFILE($,$,#19,#70,$,$);
|
||||
#75=IFCCIRCLEHOLLOWPROFILEDEF(.AREA.,$,$,0.25,0.005);
|
||||
#76=IFCCOLUMNTYPE('1qqu_K2Az3yvZSOapZmUrZ',$,'C2',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#75=IFCCIRCLEHOLLOWPROFILEDEF(.AREA.,'500.0x5.0 CHS',$,0.25,0.005);
|
||||
#76=IFCCOLUMNTYPE('3e6tIcskjDOuj1_UAWcT87',$,'C2',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#77=IFCMATERIALPROFILESET($,$,(#79),$);
|
||||
#78=IFCRELASSOCIATESMATERIAL('2YQz9JCGXAogjkmN3RZeKI',$,$,$,(#76),#77);
|
||||
#78=IFCRELASSOCIATESMATERIAL('0ahT30pYb7zQ968gWY9q1A',$,$,$,(#76),#77);
|
||||
#79=IFCMATERIALPROFILE($,$,#19,#75,$,$);
|
||||
#80=IFCRECTANGLEHOLLOWPROFILEDEF(.AREA.,$,$,0.075,0.15,0.005,0.005,0.005);
|
||||
#81=IFCCOLUMNTYPE('1rnXRgQ3X6pfk5O9j4HCLm',$,'C3',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#80=IFCRECTANGLEHOLLOWPROFILEDEF(.AREA.,'150x75x2.0 RHS',$,0.075,0.15,0.002,0.005,0.005);
|
||||
#81=IFCCOLUMNTYPE('0ZxXYg0BTFg8sbqXr50qPW',$,'C3',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#82=IFCMATERIALPROFILESET($,$,(#84),$);
|
||||
#83=IFCRELASSOCIATESMATERIAL('2CQLZ1qlzA9uN2eRrpg99c',$,$,$,(#81),#82);
|
||||
#83=IFCRELASSOCIATESMATERIAL('0ul_xSpIH2MxsZcv$ZFXG7',$,$,$,(#81),#82);
|
||||
#84=IFCMATERIALPROFILE($,$,#19,#80,$,$);
|
||||
#85=IFCISHAPEPROFILEDEF(.AREA.,'DEMO-I',$,0.1,0.2,0.005,0.01,0.005,$,$);
|
||||
#86=IFCBEAMTYPE('1xjrF860f2H9zb04Ui98Rt',$,'B1',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#86=IFCBEAMTYPE('06Td_2IhD5OgyKW34Ikv$Z',$,'B1',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#87=IFCMATERIALPROFILESET($,$,(#89),$);
|
||||
#88=IFCRELASSOCIATESMATERIAL('03i9c81690fx2ZTBBXcqkL',$,$,$,(#86),#87);
|
||||
#88=IFCRELASSOCIATESMATERIAL('2cT5kDtU11jv2sFtIKVfJa',$,$,$,(#86),#87);
|
||||
#89=IFCMATERIALPROFILE($,$,#19,#85,$,$);
|
||||
#90=IFCCSHAPEPROFILEDEF(.AREA.,'DEMO-C',$,0.2,0.1,0.0015,0.03,0.005);
|
||||
#91=IFCBEAMTYPE('3mAc_7AGP06w4CzYOlYVL2',$,'B2',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#91=IFCBEAMTYPE('1JyktsoBP8DgMbJiECPZ6d',$,'B2',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#92=IFCMATERIALPROFILESET($,$,(#94),$);
|
||||
#93=IFCRELASSOCIATESMATERIAL('2xvXgaSvL7KPR25fXz0fSE',$,$,$,(#91),#92);
|
||||
#93=IFCRELASSOCIATESMATERIAL('2$_YKuP914sBZmflM_8l1s',$,$,$,(#91),#92);
|
||||
#94=IFCMATERIALPROFILE($,$,#19,#90,$,$);
|
||||
#95=IFCWINDOWTYPE('1kxjrhA4P2dwwueZ0_nSuu',$,'WT01',$,$,$,(#136,#158),$,$,.NOTDEFINED.,.NOTDEFINED.,$,$);
|
||||
#95=IFCWINDOWTYPE('0g10V5zVP8c96j3mPV0Xvn',$,'WT01',$,$,$,(#136,#158),$,$,.NOTDEFINED.,.NOTDEFINED.,$,$);
|
||||
#96=IFCINDEXEDPOLYGONALFACE((13,17,18,14));
|
||||
#97=IFCINDEXEDPOLYGONALFACE((5,6,3,4));
|
||||
#98=IFCINDEXEDPOLYGONALFACE((7,8,2,1));
|
||||
@@ -157,13 +157,13 @@ DATA;
|
||||
#150=IFCINDEXEDPOLYCURVE(#137,(IFCLINEINDEX((5,11))),$);
|
||||
#151=IFCINDEXEDPOLYCURVE(#137,(IFCLINEINDEX((6,12))),$);
|
||||
#152=IFCGEOMETRICCURVESET((#138,#139,#140,#141,#142,#143,#144,#145,#146,#147,#148,#149,#150,#151));
|
||||
#153=IFCSHAPEREPRESENTATION(#18,'Annotation','Annotation2D',(#152));
|
||||
#153=IFCSHAPEREPRESENTATION(#18,'Body','Annotation2D',(#152));
|
||||
#154=IFCCARTESIANPOINT((0.,0.,0.));
|
||||
#155=IFCDIRECTION((1.,0.,0.));
|
||||
#156=IFCDIRECTION((0.,0.,1.));
|
||||
#157=IFCAXIS2PLACEMENT3D(#154,#156,#155);
|
||||
#158=IFCREPRESENTATIONMAP(#157,#153);
|
||||
#159=IFCDOORTYPE('0s370BWH51r8Xg03pJ5OBE',$,'DT01',$,$,$,(#204,#224),$,$,.NOTDEFINED.,.NOTDEFINED.,$,$);
|
||||
#159=IFCDOORTYPE('0nu4v3oPPFmQIz2RA1Vp_t',$,'DT01',$,$,$,(#204,#224),$,$,.NOTDEFINED.,.NOTDEFINED.,$,$);
|
||||
#160=IFCINDEXEDPOLYGONALFACE((17,16,15,14));
|
||||
#161=IFCINDEXEDPOLYGONALFACE((2,3,29,28));
|
||||
#162=IFCINDEXEDPOLYGONALFACE((27,28,29,30,32,31));
|
||||
@@ -223,13 +223,13 @@ DATA;
|
||||
#216=IFCINDEXEDPOLYCURVE(#205,(IFCLINEINDEX((11,15))),$);
|
||||
#217=IFCINDEXEDPOLYCURVE(#205,(IFCLINEINDEX((17,18)),IFCLINEINDEX((18,19)),IFCLINEINDEX((19,20)),IFCLINEINDEX((20,21)),IFCLINEINDEX((21,22)),IFCLINEINDEX((22,23)),IFCLINEINDEX((23,24)),IFCLINEINDEX((24,25)),IFCLINEINDEX((25,26)),IFCLINEINDEX((26,27)),IFCLINEINDEX((27,28)),IFCLINEINDEX((28,29))),$);
|
||||
#218=IFCGEOMETRICCURVESET((#206,#207,#208,#209,#210,#211,#212,#213,#214,#215,#216,#217));
|
||||
#219=IFCSHAPEREPRESENTATION(#18,'Annotation','Annotation2D',(#218));
|
||||
#219=IFCSHAPEREPRESENTATION(#18,'Body','Annotation2D',(#218));
|
||||
#220=IFCCARTESIANPOINT((0.,0.,0.));
|
||||
#221=IFCDIRECTION((1.,0.,0.));
|
||||
#222=IFCDIRECTION((0.,0.,1.));
|
||||
#223=IFCAXIS2PLACEMENT3D(#220,#222,#221);
|
||||
#224=IFCREPRESENTATIONMAP(#223,#219);
|
||||
#225=IFCFURNITURETYPE('227RrM$yD30RGzlTgbBH3c',$,'BUN01',$,$,$,(#946,#988),$,$,.NOTDEFINED.,.NOTDEFINED.);
|
||||
#225=IFCFURNITURETYPE('2YuVxsKJL9URJtwIhHY2GN',$,'BUN01',$,$,$,(#946,#988),$,$,.NOTDEFINED.,.NOTDEFINED.);
|
||||
#226=IFCINDEXEDPOLYGONALFACE((187,278,44));
|
||||
#227=IFCINDEXEDPOLYGONALFACE((21,52,60));
|
||||
#228=IFCINDEXEDPOLYGONALFACE((91,100,31));
|
||||
@@ -987,7 +987,7 @@ DATA;
|
||||
#980=IFCINDEXEDPOLYCURVE(#947,(IFCLINEINDEX((60,61)),IFCLINEINDEX((61,62)),IFCLINEINDEX((62,63))),$);
|
||||
#981=IFCINDEXEDPOLYCURVE(#947,(IFCLINEINDEX((64,31))),$);
|
||||
#982=IFCGEOMETRICCURVESET((#948,#949,#950,#951,#952,#953,#954,#955,#956,#957,#958,#959,#960,#961,#962,#963,#964,#965,#966,#967,#968,#969,#970,#971,#972,#973,#974,#975,#976,#977,#978,#979,#980,#981));
|
||||
#983=IFCSHAPEREPRESENTATION(#18,'Annotation','Annotation2D',(#982));
|
||||
#983=IFCSHAPEREPRESENTATION(#18,'Body','Annotation2D',(#982));
|
||||
#984=IFCCARTESIANPOINT((0.,0.,0.));
|
||||
#985=IFCDIRECTION((1.,0.,0.));
|
||||
#986=IFCDIRECTION((0.,0.,1.));
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION((),'2;1');
|
||||
FILE_NAME('EPset_Annotation.ifc','2020-01-01T00:00:00',(),(),'EPset_Annotation','EPset_Annotation',$);
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPROPERTYSETTEMPLATE('3VuPUwdCD2Qx3XDDRs0R1N',$,'EPset_Annotation','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#2,#3));
|
||||
#2=IFCSIMPLEPROPERTYTEMPLATE('2P7JN79n96Q9pElZ83LKe4',$,'ZIndex','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
|
||||
#3=IFCSIMPLEPROPERTYTEMPLATE('1Wpx_r2xj1_9w5JpI0QRJy',$,'Symbol','',.P_ENUMERATEDVALUE.,'IfcLabel',$,#4,$,$,$,.READWRITE.);
|
||||
#4=IFCPROPERTYENUMERATION('Symbol',(IFCLABEL('rectangle-tag'), IFCLABEL('door-tag')),$);
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
||||
@@ -5,20 +5,27 @@ FILE_NAME('EPset_Drawing.ifc','2020-01-01T00:00:00',(),(),'EPset_Drawing','EPset
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPROPERTYSETTEMPLATE('2JhNIvqZrFnAgxfhK0XVQX',$,'EPset_Drawing','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15));
|
||||
#1=IFCPROPERTYSETTEMPLATE('2JhNIvqZrFnAgxfhK0XVQX',$,'EPset_Drawing','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19,#20,#21));
|
||||
#2=IFCSIMPLEPROPERTYTEMPLATE('23JavTMk98ZxXhrUEnjAcf',$,'TargetView','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#3=IFCSIMPLEPROPERTYTEMPLATE('1yVWUt5H9DAOuu0OaMMLpe',$,'Scale','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#4=IFCSIMPLEPROPERTYTEMPLATE('3gsuPBtU93b8f0gg1pjkq6',$,'HumanScale','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#3=IFCSIMPLEPROPERTYTEMPLATE('1yVWUt5H9DAOuu0OaMMLpe',$,'Scale','The scale of this drawing represented as a numerator and denominator, such as 1/100',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#4=IFCSIMPLEPROPERTYTEMPLATE('3gsuPBtU93b8f0gg1pjkq6',$,'HumanScale','The scale of this drawing in human readable format, such as 1:100',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#4=IFCSIMPLEPROPERTYTEMPLATE('2T$a4OFsv2LeD5JeBKEV4f',$,'IsNTS','Whether or not the scale is intended to be significant',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#5=IFCSIMPLEPROPERTYTEMPLATE('0AK5C2UpL4$eaac2LszAx$',$,'HasUnderlay','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#6=IFCSIMPLEPROPERTYTEMPLATE('2j2ZEZR8X5tONm7kli5hM6',$,'HasLinework','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#7=IFCSIMPLEPROPERTYTEMPLATE('1ttChRysH9UuEX2FeMj5Hu',$,'HasAnnotation','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#8=IFCSIMPLEPROPERTYTEMPLATE('2NPPxuABv1huDTVh32TFgw',$,'GlobalReferencing','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#9=IFCSIMPLEPROPERTYTEMPLATE('10hT_1zrzEbRRKMXYAWvtD',$,'Metadata','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#10=IFCSIMPLEPROPERTYTEMPLATE('3Z0BXPSG5CWgtI33ioV7aj',$,'Include','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#11=IFCSIMPLEPROPERTYTEMPLATE('1RVts_g3PAw98PJA2yL3bO',$,'Exclude','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#12=IFCSIMPLEPROPERTYTEMPLATE('0c1$8NpYDEaBiJrj16jHIo',$,'Stylesheet','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.);
|
||||
#13=IFCSIMPLEPROPERTYTEMPLATE('3mRF52q81FQB$h4oTh7M45',$,'Markers','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.);
|
||||
#14=IFCSIMPLEPROPERTYTEMPLATE('1rhr_0N3LDtuORcEJP0KXM',$,'Symbols','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.);
|
||||
#15=IFCSIMPLEPROPERTYTEMPLATE('2sHDBuW7P4TROy$hL2w7ct',$,'Patterns','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.);
|
||||
#10=IFCSIMPLEPROPERTYTEMPLATE('3Z0BXPSG5CWgtI33ioV7aj',$,'Include','Selector expression to include ifc elements in the drawing',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#11=IFCSIMPLEPROPERTYTEMPLATE('1RVts_g3PAw98PJA2yL3bO',$,'Exclude','Selector expression to exclude ifc elements in the drawing',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#12=IFCSIMPLEPROPERTYTEMPLATE('0c1$8NpYDEaBiJrj16jHIo',$,'Stylesheet','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#13=IFCSIMPLEPROPERTYTEMPLATE('3mRF52q81FQB$h4oTh7M45',$,'Markers','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#14=IFCSIMPLEPROPERTYTEMPLATE('1rhr_0N3LDtuORcEJP0KXM',$,'Symbols','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#15=IFCSIMPLEPROPERTYTEMPLATE('2sHDBuW7P4TROy$hL2w7ct',$,'Patterns','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#16=IFCSIMPLEPROPERTYTEMPLATE('1$xfo9EVb26QLqmPll2_RK',$,'MetricPrecision','',.P_SINGLEVALUE.,'IfcReal',$,$,$,$,$,.READWRITE.);
|
||||
#17=IFCSIMPLEPROPERTYTEMPLATE('38uAtrp9nD_901NO42zd$7',$,'ImperialPrecision','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#18=IFCSIMPLEPROPERTYTEMPLATE('1MX0uffTL6TOvtvEJpxFmk',$,'DecimalPlaces','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
|
||||
#19=IFCSIMPLEPROPERTYTEMPLATE('0joEq0Rd10cxweEh0NeHT6',$,'JoinCriteria','Comma separated selection keys which determine what cut objects are to be joined.',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#20=IFCSIMPLEPROPERTYTEMPLATE('0nYMT3OSj5gArVniCWZRtv',$,'ShadingStyles','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||
#21=IFCSIMPLEPROPERTYTEMPLATE('3VWG22eZXBdQwdKlzMeVQH',$,'CurrentShadingStyle','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION((),'2;1');
|
||||
FILE_NAME('Psets_BBIM_Annotation.ifc','2020-01-01T00:00:00',(),(),'Psets_BBIM_Annotation','Psets_BBIM_Annotation',$);
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPROPERTYSETTEMPLATE('3VuPUwdCD2Qx3XDDRs0R1N',$,'EPset_Annotation','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#2,#3,#4));
|
||||
#2=IFCSIMPLEPROPERTYTEMPLATE('2P7JN79n96Q9pElZ83LKe4',$,'ZIndex','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
|
||||
#3=IFCSIMPLEPROPERTYTEMPLATE('1Wpx_r2xj1_9w5JpI0QRJy',$,'Symbol','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#4=IFCSIMPLEPROPERTYTEMPLATE('3q0oxMUKP47vZ4jnyG$dDb',$,'Classes','Classes separarated by spaces that end up in classes for this element in svg. Can be used to specify the text font size: small - 1.8mm; regular - 2.5mm; large - 3.5mm; header - 5mm; title - 7mm. By default regular size is used.',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#5=IFCPROPERTYSETTEMPLATE('0iKwujnQL9IevVQato8f7Z',$,'BBIM_Batting','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#6,#7));
|
||||
#6=IFCSIMPLEPROPERTYTEMPLATE('0t2LEesGT1QRQtrIZUAR8L',$,'Thickness','Batting thickness',.P_SINGLEVALUE.,'IfcPositiveLengthMeasure',$,$,$,$,$,.READWRITE.);
|
||||
#7=IFCSIMPLEPROPERTYTEMPLATE('082PndS6v2kBOiJoSboMnh',$,'Reverse pattern direction','Reverse batting pattern (swap starting and ending points)',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#8=IFCPROPERTYSETTEMPLATE('1Dx2EiZnP67xotInXpwz90',$,'BBIM_Section','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#9,#10,#11,#12,#13));
|
||||
#9=IFCSIMPLEPROPERTYTEMPLATE('2a_9s8spHDc9dZHtgg71XL',$,'ShowStartArrow','Display start arrow.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#10=IFCSIMPLEPROPERTYTEMPLATE('3i6SH_GbT7zhKea$wVE56A',$,'StartArrowSymbol','Custom symbol for the start of the section marker arrow. Need to make sure it''s present in "symbols.svg".',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#11=IFCSIMPLEPROPERTYTEMPLATE('1DtsPn5a9FG8$zXHDDMavY',$,'ShowEndArrow','Display end arrow.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#12=IFCSIMPLEPROPERTYTEMPLATE('2$6U0mLI9AiPRWeBabdY3u',$,'EndArrowSymbol','Custom symbol for the end of the section marker arrow. Need to make sure it''s present in "symbols.svg".',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#13=IFCSIMPLEPROPERTYTEMPLATE('1naFqntIL7igCY7hCaE7kq',$,'HasConnectedSectionLine','Connect or disconnect section markers with line (by default = True).',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#14=IFCPROPERTYSETTEMPLATE('3V8oZ8YRD3_O7uR5vcUleS',$,'BBIM_Documentation','',.PSET_OCCURRENCEDRIVEN.,'IfcProject',(#15,#16,#17,#18,#19,#20,#21,#22,#23));
|
||||
#15=IFCSIMPLEPROPERTYTEMPLATE('0ulAhgk3v9qfGlDILauR6J',$,'SheetsDir','Default sheets directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#16=IFCSIMPLEPROPERTYTEMPLATE('2yvlVKiQXASucfH40deCvu',$,'LayoutsDir','Default layouts directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#17=IFCSIMPLEPROPERTYTEMPLATE('2kXZqXicL3jRwsOnLM_0ho',$,'TitleblocksDir','Default titleblocks directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#18=IFCSIMPLEPROPERTYTEMPLATE('1lmOfo9Bf9beMBJkCZKf5Y',$,'DrawingsDir','Default drawings directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#19=IFCSIMPLEPROPERTYTEMPLATE('30cOKpb4D9CADKM04$N9X3',$,'StylesheetPath','Default stylesheet CSS',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#20=IFCSIMPLEPROPERTYTEMPLATE('23tejOrxj859R_eCRp1AFP',$,'MarkersPath','Default markers SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#21=IFCSIMPLEPROPERTYTEMPLATE('1UDakJ5_f7kBhggNSW4$h5',$,'SymbolsPath','Default symbols SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#22=IFCSIMPLEPROPERTYTEMPLATE('0d53LEtgLDQxnv__NfgH7i',$,'PatternsPath','Default patterns SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#23=IFCSIMPLEPROPERTYTEMPLATE('26qFNMv7nCHgU6Jd7Anga5',$,'ShadingStylesPath','Default shading styles',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#25,#26,#27,#28));
|
||||
#25=IFCSIMPLEPROPERTYTEMPLATE('1rL2AbQsXD8RbpoWH5pYOV',$,'ShowDescriptionOnly','Hide the measurement values and show only annotation description',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#26=IFCSIMPLEPROPERTYTEMPLATE('0SVyOfB0rC2xNfdRYf3XvY',$,'SuppressZeroInches','Suppress 0 inch values in dimension annotation text (for example: 12'' - 0" -> 12'')',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#27=IFCSIMPLEPROPERTYTEMPLATE('2bUmj458PBqPAtUoI3MXsb',$,'TextPrefix','Text to add before annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#28=IFCSIMPLEPROPERTYTEMPLATE('0bnzttUb9BPuN597uNTXOE',$,'TextSuffix','Text to add after annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<svg baseProfile="full" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="rectangle-tag">
|
||||
<rect x="-6" y="-2.5" width="12" height="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
</g>
|
||||
<g id="door-tag">
|
||||
<circle cy="1.75" r="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
<line x1="-5" y1="1.75" x2="5" y2="1.75" style="stroke: black; stroke-width: 0.25;" />
|
||||
</g>
|
||||
<g id="elevation-arrow">
|
||||
<path style="fill: black;" d="M -7.07106 0 0 -7.07106 7.07106 0" />
|
||||
</g>
|
||||
<g id="elevation-tag">
|
||||
<circle r="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
<line x1="-5" y1="0" x2="5" y2="0" style="stroke: black; stroke-width: 0.25;" />
|
||||
</g>
|
||||
<g id="section-arrow">
|
||||
<path style="fill: black;" d="M -7.07106 0 0 -7.07106 7.07106 0" />
|
||||
</g>
|
||||
<g id="section-tag">
|
||||
<circle r="5" fill="white" stroke="black" style="stroke-width: 0.25;" />
|
||||
<line x1="-5" y1="0" x2="5" y2="0" style="stroke: black; stroke-width: 0.25;" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 841 594"
|
||||
id="root"
|
||||
version="1.1"
|
||||
height="594mm"
|
||||
width="841mm">
|
||||
width="841mm"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs901" />
|
||||
<metadata
|
||||
@@ -20,7 +20,6 @@
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
@@ -44,146 +43,10 @@
|
||||
width="3027.1016"
|
||||
id="rect116616"
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.88976377;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
id="text116526"
|
||||
y="909.15491"
|
||||
x="113.70713"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.1536px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15.1536px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.94488188;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="909.15491"
|
||||
x="113.70713"
|
||||
id="tspan116524">REV. NO.</tspan></text>
|
||||
<path
|
||||
id="path116530"
|
||||
d="M 75.590564,895.24802 H 3102.9921"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path116532"
|
||||
d="M 151.6811,895.24802 V 1046.9291"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 454.04331,895.24802 V 1046.9291"
|
||||
id="path116534" />
|
||||
<path
|
||||
id="path116536"
|
||||
d="M 529.63386,895.24802 V 1046.4302"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 605.22441,895.24802 V 1046.9291"
|
||||
id="path116538" />
|
||||
<path
|
||||
id="path116540"
|
||||
d="M 75.590564,914.14565 H 605.22441"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 75.590564,933.04329 H 605.22441"
|
||||
id="path116542" />
|
||||
<path
|
||||
id="path116544"
|
||||
d="M 75.590564,951.94093 H 605.22441"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 75.590564,970.83857 H 605.22441"
|
||||
id="path116546" />
|
||||
<path
|
||||
id="path116548"
|
||||
d="M 75.590564,989.73621 H 605.22441"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 75.590564,1008.6338 H 605.22441"
|
||||
id="path116550" />
|
||||
<path
|
||||
id="path116552"
|
||||
d="M 75.590564,1027.5315 H 605.22441"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path116576"
|
||||
d="M 2800.5,895.24802 V 1046.9291"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path116578"
|
||||
d="m 2800.5,1008.6338 h 302.4921"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path116598"
|
||||
d="m 3027.4027,1008.6338 v 38.2953"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.1536px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="302.86591"
|
||||
y="909.15491"
|
||||
id="text1395"><tspan
|
||||
id="tspan1393"
|
||||
x="302.86591"
|
||||
y="909.15491"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15.1536px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.94488188;stroke-miterlimit:4;stroke-dasharray:none">DESCRIPTION</tspan></text>
|
||||
<text
|
||||
id="text1399"
|
||||
y="909.15491"
|
||||
x="491.97513"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.1536px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15.1536px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.94488188;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="909.15491"
|
||||
x="491.97513"
|
||||
id="tspan1397">AUTHOR</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:16.0591px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="568.05585"
|
||||
y="909.15485"
|
||||
id="text1403"><tspan
|
||||
id="tspan1401"
|
||||
x="568.05585"
|
||||
y="909.15485"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.0591px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.94488188;stroke-miterlimit:4;stroke-dasharray:none">DATE</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:11.2271px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="2839.5081"
|
||||
y="1020.4988"
|
||||
id="text1421"><tspan
|
||||
id="tspan1419"
|
||||
x="2839.5081"
|
||||
y="1020.4988"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.2271px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.94488188;stroke-miterlimit:4;stroke-dasharray:none">DRAWING NUMBER</tspan></text>
|
||||
<text
|
||||
id="text1429"
|
||||
y="1020.4988"
|
||||
x="3038.5586"
|
||||
style="font-style:normal;font-weight:normal;font-size:11.2271px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.94488188;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.2271px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.94488188;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="1020.4988"
|
||||
x="3038.5586"
|
||||
id="tspan1427">REV</tspan></text>
|
||||
<text
|
||||
id="text2529"
|
||||
y="1036.1166"
|
||||
x="3030.9653"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.3918px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.999999px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.999999px"
|
||||
y="1036.1166"
|
||||
x="3030.9653"
|
||||
id="tspan2527">{{Revision}}</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.3918px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.999999px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="2804.7021"
|
||||
y="1036.1166"
|
||||
id="text2533"><tspan
|
||||
id="tspan2531"
|
||||
x="2804.7021"
|
||||
y="1036.1166"
|
||||
style="stroke-width:0.999999px">{{Identification}} - {{Name}}</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458334,-3.180917e-5,297.00003)"
|
||||
@@ -205,4 +68,260 @@
|
||||
transform="matrix(0.26458333,0,0,0.26458334,-3.180917e-5,297.00003)"
|
||||
id="g90677"
|
||||
style="stroke-width:3.77953" />
|
||||
<g
|
||||
id="g38171"
|
||||
transform="translate(411.014,286.96036)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,246.86771 V 286.75"
|
||||
id="path116576" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,276.8677 H 410"
|
||||
id="path116578" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 390.00031,276.8677 V 287"
|
||||
id="path116598" />
|
||||
<text
|
||||
id="text1421"
|
||||
y="280.00699"
|
||||
x="340.28653"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.9705px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.9705px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="280.00699"
|
||||
x="340.28653"
|
||||
id="tspan1419">DRAWING NUMBER</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.05925px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="393.00568"
|
||||
y="280.0592"
|
||||
id="text1429"><tspan
|
||||
id="tspan1427"
|
||||
x="393.00568"
|
||||
y="280.0592"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.05925px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25747;stroke-miterlimit:4;stroke-dasharray:none">REV</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="390.94287"
|
||||
y="284.13919"
|
||||
id="text2529"><tspan
|
||||
id="tspan2527"
|
||||
x="390.94287"
|
||||
y="284.13919"
|
||||
style="stroke-width:0.264583px">{{Revision}}</tspan></text>
|
||||
<text
|
||||
id="text2533"
|
||||
y="284.13919"
|
||||
x="331.07742"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.265;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.265;stroke-dasharray:none"
|
||||
y="284.13919"
|
||||
x="331.07742"
|
||||
id="tspan2531">{{Identification}}</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,266.868 H 410"
|
||||
id="path36736" />
|
||||
<text
|
||||
id="text36740"
|
||||
y="270.05899"
|
||||
x="339.00919"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.05925px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.05925px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25747;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="270.05899"
|
||||
x="339.00919"
|
||||
id="tspan36738">DRAWING TITLE</tspan></text>
|
||||
<text
|
||||
id="text36744"
|
||||
y="275.05634"
|
||||
x="330.99438"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.96055px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.371;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.371;stroke-dasharray:none"
|
||||
y="275.05634"
|
||||
x="330.99438"
|
||||
id="tspan36742">{{Name}}</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 390.00031,246.86771 V 266.993"
|
||||
id="path36746" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.88677px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.169851;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="397.04108"
|
||||
y="249.72177"
|
||||
id="text36677"><tspan
|
||||
id="tspan36675"
|
||||
x="397.04108"
|
||||
y="249.72177"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.88677px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.169851;stroke-miterlimit:4;stroke-dasharray:none">GRID NORTH</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.88677px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.169851;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="338.77008"
|
||||
y="249.72177"
|
||||
id="text36752"><tspan
|
||||
id="tspan36750"
|
||||
x="335.76562"
|
||||
y="249.72177"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.88677px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.169851;stroke-miterlimit:4;stroke-dasharray:none">COMPANY</tspan></text>
|
||||
<g
|
||||
id="g37148"
|
||||
transform="translate(399.87519,258.25776)">
|
||||
<g
|
||||
id="g37140"
|
||||
data-type="grid-north">
|
||||
<path
|
||||
id="path11652"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 0,0 V 7.12566 Z" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 7.3079,3e-5 H -7.30798"
|
||||
id="path36547" />
|
||||
<circle
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="path36601"
|
||||
cx="-3.8305665e-05"
|
||||
cy="4.15625e-05"
|
||||
r="5" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="m -5.00004,4e-5 5,-5 5,5 H 3.94162 L -4e-5,-3.94162 -3.9417,4e-5 Z"
|
||||
id="path36671" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M -4e-5,-7.12545 V 3e-5"
|
||||
id="path36673" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g38492"
|
||||
transform="translate(9.7896584,287.21036)">
|
||||
<text
|
||||
id="text116526"
|
||||
y="250.54721"
|
||||
x="20.085007"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="250.54721"
|
||||
x="20.085007"
|
||||
id="tspan116524">REV. NO.</tspan></text>
|
||||
<path
|
||||
id="path116532"
|
||||
d="M 30.132288,246.86771 V 287"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 110.13229,246.86771 V 287"
|
||||
id="path116534" />
|
||||
<path
|
||||
id="path116536"
|
||||
d="M 130.13229,246.86771 V 286.868"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 150.13229,246.86771 V 287"
|
||||
id="path116538" />
|
||||
<path
|
||||
id="path116540"
|
||||
d="M 10,251.86771 H 170.132"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,256.86771 H 170.132"
|
||||
id="path116542" />
|
||||
<path
|
||||
id="path116544"
|
||||
d="M 10,261.86771 H 170.132"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,266.86771 H 170.132"
|
||||
id="path116546" />
|
||||
<path
|
||||
id="path116548"
|
||||
d="M 10,271.86771 H 170.132"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,276.8677 H 170.132"
|
||||
id="path116550" />
|
||||
<path
|
||||
id="path116552"
|
||||
d="M 10,281.86772 H 170.132"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="70.13327"
|
||||
y="250.54721"
|
||||
id="text1395"><tspan
|
||||
id="tspan1393"
|
||||
x="70.13327"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DESCRIPTION</tspan></text>
|
||||
<text
|
||||
id="text1399"
|
||||
y="250.54721"
|
||||
x="120.16841"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="250.54721"
|
||||
x="120.16841"
|
||||
id="tspan1397">AUTHOR</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="140.29811"
|
||||
y="250.54721"
|
||||
id="text1403"><tspan
|
||||
id="tspan1401"
|
||||
x="140.29811"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">ISSUED</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="180.14232"
|
||||
y="250.54721"
|
||||
id="text36130"><tspan
|
||||
id="tspan36128"
|
||||
x="175.72011"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">NOTES</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="194.37886"
|
||||
y="255.5477"
|
||||
id="text36768"><tspan
|
||||
id="tspan36766"
|
||||
x="189.95665"
|
||||
y="255.5477"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DO NOT SCALE DRAWINGS</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 170.132,246.86771 V 287"
|
||||
id="path36836" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="160.29811"
|
||||
y="250.54721"
|
||||
id="text36842"><tspan
|
||||
id="tspan36840"
|
||||
x="160.29811"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DATE</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 20 KiB |
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="594mm"
|
||||
height="420mm"
|
||||
version="1.1"
|
||||
id="root"
|
||||
viewBox="0 0 594 420">
|
||||
viewBox="0 0 594 420"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs901" />
|
||||
<metadata
|
||||
@@ -20,7 +20,6 @@
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
@@ -40,146 +39,10 @@
|
||||
width="553.5"
|
||||
id="rect116616"
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
id="text116526"
|
||||
y="363.54721"
|
||||
x="30.085009"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="363.54721"
|
||||
x="30.085009"
|
||||
id="tspan116524">REV. NO.</tspan></text>
|
||||
<path
|
||||
id="path116530"
|
||||
d="m 20.000001,359.86771 553.749999,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path116532"
|
||||
d="M 40.132289,359.86771 V 400"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 120.13229,359.86771 V 400"
|
||||
id="path116534" />
|
||||
<path
|
||||
id="path116536"
|
||||
d="M 140.13229,359.86771 V 399.868"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 160.13229,359.86771 V 400"
|
||||
id="path116538" />
|
||||
<path
|
||||
id="path116540"
|
||||
d="M 20.000001,364.86771 H 160.13229"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 20.000001,369.86771 H 160.13229"
|
||||
id="path116542" />
|
||||
<path
|
||||
id="path116544"
|
||||
d="M 20.000001,374.86771 H 160.13229"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 20.000001,379.86771 H 160.13229"
|
||||
id="path116546" />
|
||||
<path
|
||||
id="path116548"
|
||||
d="M 20.000001,384.86771 H 160.13229"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 20.000001,389.8677 H 160.13229"
|
||||
id="path116550" />
|
||||
<path
|
||||
id="path116552"
|
||||
d="M 20.000001,394.86772 H 160.13229"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="80.13327"
|
||||
y="363.54721"
|
||||
id="text1395"><tspan
|
||||
id="tspan1393"
|
||||
x="80.13327"
|
||||
y="363.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DESCRIPTION</tspan></text>
|
||||
<text
|
||||
id="text1399"
|
||||
y="363.54721"
|
||||
x="130.16841"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="363.54721"
|
||||
x="130.16841"
|
||||
id="tspan1397">AUTHOR</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="150.29811"
|
||||
y="363.54721"
|
||||
id="text1403"><tspan
|
||||
id="tspan1401"
|
||||
x="150.29811"
|
||||
y="363.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DATE</tspan></text>
|
||||
<path
|
||||
id="path116576"
|
||||
d="M 493.96563,359.86771 V 400"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path116578"
|
||||
d="M 493.96563,389.8677 H 574"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path116598"
|
||||
d="M 554.00031,389.8677 V 400"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.9705px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="504.28653"
|
||||
y="393.00699"
|
||||
id="text1421"><tspan
|
||||
id="tspan1419"
|
||||
x="504.28653"
|
||||
y="393.00699"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.9705px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DRAWING NUMBER</tspan></text>
|
||||
<text
|
||||
id="text1429"
|
||||
y="393.00699"
|
||||
x="556.9519"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.9705px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.9705px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="393.00699"
|
||||
x="556.9519"
|
||||
id="tspan1427">REV</tspan></text>
|
||||
<text
|
||||
id="text2529"
|
||||
y="397.13919"
|
||||
x="554.94287"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.264583px"
|
||||
y="397.13919"
|
||||
x="554.94287"
|
||||
id="tspan2527">{{Revision}}</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="495.07742"
|
||||
y="397.13919"
|
||||
id="text2533"><tspan
|
||||
id="tspan2531"
|
||||
x="495.07742"
|
||||
y="397.13919"
|
||||
style="stroke-width:0.264583px">{{Identification}} - {{Name}}</tspan></text>
|
||||
<g
|
||||
style="stroke-width:3.77953"
|
||||
id="g90669"
|
||||
@@ -200,4 +63,260 @@
|
||||
style="stroke-width:3.77953"
|
||||
id="g90677"
|
||||
transform="matrix(0.26458333,0,0,0.26458334,-3.180917e-5,297.00003)" />
|
||||
<g
|
||||
id="g38171"
|
||||
transform="translate(163.75769,113)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,246.86771 V 286.75"
|
||||
id="path116576" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,276.8677 H 410"
|
||||
id="path116578" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 390.00031,276.8677 V 287"
|
||||
id="path116598" />
|
||||
<text
|
||||
id="text1421"
|
||||
y="280.00699"
|
||||
x="340.28653"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.9705px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.9705px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="280.00699"
|
||||
x="340.28653"
|
||||
id="tspan1419">DRAWING NUMBER</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.05925px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="393.00568"
|
||||
y="280.0592"
|
||||
id="text1429"><tspan
|
||||
id="tspan1427"
|
||||
x="393.00568"
|
||||
y="280.0592"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.05925px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25747;stroke-miterlimit:4;stroke-dasharray:none">REV</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="390.94287"
|
||||
y="284.13919"
|
||||
id="text2529"><tspan
|
||||
id="tspan2527"
|
||||
x="390.94287"
|
||||
y="284.13919"
|
||||
style="stroke-width:0.264583px">{{Revision}}</tspan></text>
|
||||
<text
|
||||
id="text2533"
|
||||
y="284.13919"
|
||||
x="331.07742"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.265;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.265;stroke-dasharray:none"
|
||||
y="284.13919"
|
||||
x="331.07742"
|
||||
id="tspan2531">{{Identification}}</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,266.868 H 410"
|
||||
id="path36736" />
|
||||
<text
|
||||
id="text36740"
|
||||
y="270.05899"
|
||||
x="339.00919"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.05925px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.05925px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25747;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="270.05899"
|
||||
x="339.00919"
|
||||
id="tspan36738">DRAWING TITLE</tspan></text>
|
||||
<text
|
||||
id="text36744"
|
||||
y="275.05634"
|
||||
x="330.99438"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.96055px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.371;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.371;stroke-dasharray:none"
|
||||
y="275.05634"
|
||||
x="330.99438"
|
||||
id="tspan36742">{{Name}}</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 390.00031,246.86771 V 266.993"
|
||||
id="path36746" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.88677px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.169851;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="397.04108"
|
||||
y="249.72177"
|
||||
id="text36677"><tspan
|
||||
id="tspan36675"
|
||||
x="397.04108"
|
||||
y="249.72177"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.88677px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.169851;stroke-miterlimit:4;stroke-dasharray:none">GRID NORTH</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.88677px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.169851;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="338.77008"
|
||||
y="249.72177"
|
||||
id="text36752"><tspan
|
||||
id="tspan36750"
|
||||
x="335.76562"
|
||||
y="249.72177"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.88677px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.169851;stroke-miterlimit:4;stroke-dasharray:none">COMPANY</tspan></text>
|
||||
<g
|
||||
id="g37148"
|
||||
transform="translate(399.87519,258.25776)">
|
||||
<g
|
||||
id="g37140"
|
||||
data-type="grid-north">
|
||||
<path
|
||||
id="path11652"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 0,0 V 7.12566 Z" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 7.3079,3e-5 H -7.30798"
|
||||
id="path36547" />
|
||||
<circle
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="path36601"
|
||||
cx="-3.8305665e-05"
|
||||
cy="4.15625e-05"
|
||||
r="5" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="m -5.00004,4e-5 5,-5 5,5 H 3.94162 L -4e-5,-3.94162 -3.9417,4e-5 Z"
|
||||
id="path36671" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M -4e-5,-7.12545 V 3e-5"
|
||||
id="path36673" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g38492"
|
||||
transform="translate(10.000001,113)">
|
||||
<text
|
||||
id="text116526"
|
||||
y="250.54721"
|
||||
x="20.085007"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="250.54721"
|
||||
x="20.085007"
|
||||
id="tspan116524">REV. NO.</tspan></text>
|
||||
<path
|
||||
id="path116532"
|
||||
d="M 30.132288,246.86771 V 287"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 110.13229,246.86771 V 287"
|
||||
id="path116534" />
|
||||
<path
|
||||
id="path116536"
|
||||
d="M 130.13229,246.86771 V 286.868"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 150.13229,246.86771 V 287"
|
||||
id="path116538" />
|
||||
<path
|
||||
id="path116540"
|
||||
d="M 10,251.86771 H 170.132"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,256.86771 H 170.132"
|
||||
id="path116542" />
|
||||
<path
|
||||
id="path116544"
|
||||
d="M 10,261.86771 H 170.132"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,266.86771 H 170.132"
|
||||
id="path116546" />
|
||||
<path
|
||||
id="path116548"
|
||||
d="M 10,271.86771 H 170.132"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,276.8677 H 170.132"
|
||||
id="path116550" />
|
||||
<path
|
||||
id="path116552"
|
||||
d="M 10,281.86772 H 170.132"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="70.13327"
|
||||
y="250.54721"
|
||||
id="text1395"><tspan
|
||||
id="tspan1393"
|
||||
x="70.13327"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DESCRIPTION</tspan></text>
|
||||
<text
|
||||
id="text1399"
|
||||
y="250.54721"
|
||||
x="120.16841"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="250.54721"
|
||||
x="120.16841"
|
||||
id="tspan1397">AUTHOR</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="140.29811"
|
||||
y="250.54721"
|
||||
id="text1403"><tspan
|
||||
id="tspan1401"
|
||||
x="140.29811"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">ISSUED</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="180.14232"
|
||||
y="250.54721"
|
||||
id="text36130"><tspan
|
||||
id="tspan36128"
|
||||
x="175.72011"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">NOTES</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="194.37886"
|
||||
y="255.5477"
|
||||
id="text36768"><tspan
|
||||
id="tspan36766"
|
||||
x="189.95665"
|
||||
y="255.5477"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DO NOT SCALE DRAWINGS</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 170.132,246.86771 V 287"
|
||||
id="path36836" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="160.29811"
|
||||
y="250.54721"
|
||||
id="text36842"><tspan
|
||||
id="tspan36840"
|
||||
x="160.29811"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DATE</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 20 KiB |
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="420mm"
|
||||
height="297mm"
|
||||
version="1.1"
|
||||
id="root"
|
||||
viewBox="0 0 420 297">
|
||||
viewBox="0 0 420 297"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs901" />
|
||||
<metadata
|
||||
@@ -20,7 +20,6 @@
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
@@ -40,150 +39,10 @@
|
||||
width="399.5"
|
||||
id="rect116616"
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.49999897;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
id="text116526"
|
||||
y="250.54721"
|
||||
x="20.085007"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="250.54721"
|
||||
x="20.085007"
|
||||
id="tspan116524">REV. NO.</tspan></text>
|
||||
<path
|
||||
id="path116530"
|
||||
d="m 10,246.86771 399.75,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path116532"
|
||||
d="M 30.132288,246.86771 V 287"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 110.13229,246.86771 V 287"
|
||||
id="path116534" />
|
||||
<path
|
||||
id="path116536"
|
||||
d="M 130.13229,246.86771 V 286.868"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 150.13229,246.86771 V 287"
|
||||
id="path116538" />
|
||||
<path
|
||||
id="path116540"
|
||||
d="M 10,251.86771 H 150.13229"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,256.86771 H 150.13229"
|
||||
id="path116542" />
|
||||
<path
|
||||
id="path116544"
|
||||
d="M 10,261.86771 H 150.13229"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,266.86771 H 150.13229"
|
||||
id="path116546" />
|
||||
<path
|
||||
id="path116548"
|
||||
d="M 10,271.86771 H 150.13229"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10,276.8677 H 150.13229"
|
||||
id="path116550" />
|
||||
<path
|
||||
id="path116552"
|
||||
d="M 10,281.86772 H 150.13229"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="70.13327"
|
||||
y="250.54721"
|
||||
id="text1395"><tspan
|
||||
id="tspan1393"
|
||||
x="70.13327"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DESCRIPTION</tspan></text>
|
||||
<text
|
||||
id="text1399"
|
||||
y="250.54721"
|
||||
x="120.16841"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="250.54721"
|
||||
x="120.16841"
|
||||
id="tspan1397">AUTHOR</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="140.29811"
|
||||
y="250.54721"
|
||||
id="text1403"><tspan
|
||||
id="tspan1401"
|
||||
x="140.29811"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DATE</tspan></text>
|
||||
<g
|
||||
transform="translate(-154)"
|
||||
id="g3735">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 483.96563,246.86771 V 287"
|
||||
id="path116576" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 483.96563,276.8677 H 564"
|
||||
id="path116578" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 544.00031,276.8677 V 287"
|
||||
id="path116598" />
|
||||
<text
|
||||
id="text1421"
|
||||
y="280.00699"
|
||||
x="494.28653"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.9705px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.9705px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="280.00699"
|
||||
x="494.28653"
|
||||
id="tspan1419">DRAWING NUMBER</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.9705px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="546.9519"
|
||||
y="280.00699"
|
||||
id="text1429"><tspan
|
||||
id="tspan1427"
|
||||
x="546.9519"
|
||||
y="280.00699"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.9705px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">REV</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="544.94287"
|
||||
y="284.13919"
|
||||
id="text2529"><tspan
|
||||
id="tspan2527"
|
||||
x="544.94287"
|
||||
y="284.13919"
|
||||
style="stroke-width:0.264583px">{{Revision}}</tspan></text>
|
||||
<text
|
||||
id="text2533"
|
||||
y="284.13919"
|
||||
x="485.07742"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.264583px"
|
||||
y="284.13919"
|
||||
x="485.07742"
|
||||
id="tspan2531">{{Identification}} - {{Name}}</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
style="stroke-width:3.77953"
|
||||
id="g90669"
|
||||
@@ -204,4 +63,271 @@
|
||||
style="stroke-width:3.77953"
|
||||
id="g90677"
|
||||
transform="matrix(0.26458333,0,0,0.26458334,-3.180917e-5,297.00003)" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:100%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="162.3047"
|
||||
y="256.66803"
|
||||
id="text36756" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:20.4013px;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT, Normal';text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264999;stroke-linecap:round;stroke-dasharray:none"
|
||||
x="161.2028"
|
||||
y="266.93387"
|
||||
id="text36760" />
|
||||
<g
|
||||
id="g38492">
|
||||
<text
|
||||
id="text116526"
|
||||
y="250.54721"
|
||||
x="20.085007"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="250.54721"
|
||||
x="20.085007"
|
||||
id="tspan116524">REV. NO.</tspan></text>
|
||||
<path
|
||||
id="path116532"
|
||||
d="M 30.132288,246.86771 V 287"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 110.13229,246.86771 V 287"
|
||||
id="path116534" />
|
||||
<path
|
||||
id="path116536"
|
||||
d="M 130.13229,246.86771 V 286.868"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 150.13229,246.86771 V 287"
|
||||
id="path116538" />
|
||||
<path
|
||||
id="path116540"
|
||||
d="m 10,251.86771 160.132,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 10,256.86771 160.132,0"
|
||||
id="path116542" />
|
||||
<path
|
||||
id="path116544"
|
||||
d="m 10,261.86771 160.132,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 10,266.86771 160.132,0"
|
||||
id="path116546" />
|
||||
<path
|
||||
id="path116548"
|
||||
d="m 10,271.86771 160.132,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 10,276.8677 160.132,0"
|
||||
id="path116550" />
|
||||
<path
|
||||
id="path116552"
|
||||
d="m 10,281.86772 160.132,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="70.13327"
|
||||
y="250.54721"
|
||||
id="text1395"><tspan
|
||||
id="tspan1393"
|
||||
x="70.13327"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DESCRIPTION</tspan></text>
|
||||
<text
|
||||
id="text1399"
|
||||
y="250.54721"
|
||||
x="120.16841"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.00939px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.00939px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="250.54721"
|
||||
x="120.16841"
|
||||
id="tspan1397">AUTHOR</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="140.29811"
|
||||
y="250.54721"
|
||||
id="text1403"><tspan
|
||||
id="tspan1401"
|
||||
x="140.29811"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">ISSUED</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="180.14232"
|
||||
y="250.54721"
|
||||
id="text36130"><tspan
|
||||
id="tspan36128"
|
||||
x="175.72011"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">NOTES</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="194.37886"
|
||||
y="255.5477"
|
||||
id="text36768"><tspan
|
||||
id="tspan36766"
|
||||
x="189.95665"
|
||||
y="255.5477"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DO NOT SCALE DRAWINGS</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 170.132,246.86771 V 287"
|
||||
id="path36836" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.24897px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="160.29811"
|
||||
y="250.54721"
|
||||
id="text36842"><tspan
|
||||
id="tspan36840"
|
||||
x="160.29811"
|
||||
y="250.54721"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.24897px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none">DATE</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g38171"
|
||||
transform="translate(-0.25000095)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,246.86771 V 286.75"
|
||||
id="path116576" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,276.8677 H 410"
|
||||
id="path116578" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 390.00031,276.8677 V 287"
|
||||
id="path116598" />
|
||||
<text
|
||||
id="text1421"
|
||||
y="280.00699"
|
||||
x="340.28653"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.9705px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.9705px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="280.00699"
|
||||
x="340.28653"
|
||||
id="tspan1419">DRAWING NUMBER</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.05925px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="393.00568"
|
||||
y="280.0592"
|
||||
id="text1429"><tspan
|
||||
id="tspan1427"
|
||||
x="393.00568"
|
||||
y="280.0592"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.05925px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25747;stroke-miterlimit:4;stroke-dasharray:none">REV</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="390.94287"
|
||||
y="284.13919"
|
||||
id="text2529"><tspan
|
||||
id="tspan2527"
|
||||
x="390.94287"
|
||||
y="284.13919"
|
||||
style="stroke-width:0.264583px">{{Revision}}</tspan></text>
|
||||
<text
|
||||
id="text2533"
|
||||
y="284.13919"
|
||||
x="331.07742"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.265;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.265;stroke-dasharray:none"
|
||||
y="284.13919"
|
||||
x="331.07742"
|
||||
id="tspan2531">{{Identification}}</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 329.96563,266.868 H 410"
|
||||
id="path36736" />
|
||||
<text
|
||||
id="text36740"
|
||||
y="270.05899"
|
||||
x="339.00919"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.05925px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.05925px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.25747;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="270.05899"
|
||||
x="339.00919"
|
||||
id="tspan36738">DRAWING TITLE</tspan></text>
|
||||
<text
|
||||
id="text36744"
|
||||
y="275.05634"
|
||||
x="330.99438"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.96055px;line-height:125%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.371;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.371;stroke-dasharray:none"
|
||||
y="275.05634"
|
||||
x="330.99438"
|
||||
id="tspan36742">{{Name}}</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 390.00031,246.86771 V 266.993"
|
||||
id="path36746" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.88677px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.169851;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="397.04108"
|
||||
y="249.72177"
|
||||
id="text36677"><tspan
|
||||
id="tspan36675"
|
||||
x="397.04108"
|
||||
y="249.72177"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.88677px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.169851;stroke-miterlimit:4;stroke-dasharray:none">GRID NORTH</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.88677px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.169851;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="338.77008"
|
||||
y="249.72177"
|
||||
id="text36752"><tspan
|
||||
id="tspan36750"
|
||||
x="335.76562"
|
||||
y="249.72177"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.88677px;line-height:100%;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.169851;stroke-miterlimit:4;stroke-dasharray:none">COMPANY</tspan></text>
|
||||
<g
|
||||
id="g37148"
|
||||
transform="translate(399.87519,258.25776)">
|
||||
<g
|
||||
id="g37140"
|
||||
data-type="grid-north">
|
||||
<path
|
||||
id="path11652"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 0,0 V 7.12566 Z" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 7.3079,3e-5 H -7.30798"
|
||||
id="path36547" />
|
||||
<circle
|
||||
style="fill:none;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="path36601"
|
||||
cx="-3.8305665e-05"
|
||||
cy="4.15625e-05"
|
||||
r="5" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.25;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="m -5.00004,4e-5 5,-5 5,5 H 3.94162 L -4e-5,-3.94162 -3.9417,4e-5 Z"
|
||||
id="path36671" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M -4e-5,-7.12545 V 3e-5"
|
||||
id="path36673" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 20 KiB |
@@ -44,10 +44,8 @@ class IfcExporter:
|
||||
self.file = IfcStore.get_file()
|
||||
self.set_header()
|
||||
IfcStore.update_cache()
|
||||
if bpy.context.scene.BIMProjectProperties.is_authoring:
|
||||
self.sync_deletions()
|
||||
self.sync_all_objects()
|
||||
self.sync_edited_objects()
|
||||
self.sync_all_objects()
|
||||
self.sync_edited_objects()
|
||||
extension = self.ifc_export_settings.output_file.split(".")[-1].lower()
|
||||
if extension == "ifczip":
|
||||
with tempfile.TemporaryDirectory() as unzipped_path:
|
||||
@@ -87,19 +85,6 @@ class IfcExporter:
|
||||
self.get_application_name(), self.get_application_version()
|
||||
)
|
||||
|
||||
def sync_deletions(self):
|
||||
results = []
|
||||
for ifc_definition_id in IfcStore.deleted_ids:
|
||||
try:
|
||||
product = self.file.by_id(ifc_definition_id)
|
||||
if hasattr(product, "GlobalId"):
|
||||
results.append(product.GlobalId)
|
||||
except:
|
||||
continue
|
||||
ifcopenshell.api.run("root.remove_product", self.file, **{"product": product})
|
||||
IfcStore.deleted_ids.clear()
|
||||
return results
|
||||
|
||||
def sync_all_objects(self):
|
||||
results = []
|
||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
||||
@@ -126,7 +111,8 @@ class IfcExporter:
|
||||
continue
|
||||
try:
|
||||
if isinstance(obj, bpy.types.Material):
|
||||
blenderbim.core.style.update_style_colours(tool.Ifc, tool.Style, obj=obj)
|
||||
if tool.Ifc.has_changed_shading(obj):
|
||||
blenderbim.core.style.update_style_colours(tool.Ifc, tool.Style, obj=obj)
|
||||
else:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if element:
|
||||
@@ -149,10 +135,10 @@ class IfcExporter:
|
||||
return checksum != str([s.id() for s in tool.Geometry.get_styles(obj) if s])
|
||||
|
||||
def sync_object_placement(self, obj):
|
||||
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
if not tool.Ifc.is_moved(obj):
|
||||
return
|
||||
blender_matrix = np.array(obj.matrix_world)
|
||||
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
if (obj.scale - Vector((1.0, 1.0, 1.0))).length > 1e-4:
|
||||
bpy.ops.bim.update_representation(obj=obj.name)
|
||||
return element
|
||||
|
||||
@@ -22,21 +22,18 @@ import addon_utils
|
||||
import ifcopenshell.api.owner.settings
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.core.owner as core_owner
|
||||
from blenderbim.bim.module.drawing.prop import RasterStyleProperty
|
||||
from bpy.app.handlers import persistent
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.owner.prop import get_user_person, get_user_organisation
|
||||
from blenderbim.bim.module.model.data import AuthoringData
|
||||
from ifcopenshell.api.material.data import Data as MaterialData
|
||||
from ifcopenshell.api.type.data import Data as TypeData
|
||||
from mathutils import Vector
|
||||
from math import cos, degrees
|
||||
|
||||
|
||||
global_subscription_owner = object()
|
||||
|
||||
|
||||
def mode_callback(obj, data):
|
||||
if not bpy.context.scene.BIMProjectProperties.is_authoring:
|
||||
return
|
||||
objects = bpy.context.selected_objects
|
||||
if bpy.context.active_object:
|
||||
objects += [bpy.context.active_object]
|
||||
@@ -49,9 +46,9 @@ def mode_callback(obj, data):
|
||||
):
|
||||
continue
|
||||
if obj.data.BIMMeshProperties.ifc_definition_id:
|
||||
IfcStore.edited_objs.add(obj)
|
||||
tool.Ifc.edit(obj)
|
||||
elif IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id).is_a("IfcGridAxis"):
|
||||
IfcStore.edited_objs.add(obj)
|
||||
tool.Ifc.edit(obj)
|
||||
|
||||
|
||||
def name_callback(obj, data):
|
||||
@@ -67,7 +64,6 @@ def name_callback(obj, data):
|
||||
if isinstance(obj, bpy.types.Material):
|
||||
if obj.BIMObjectProperties.ifc_definition_id:
|
||||
IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id).Name = obj.name
|
||||
MaterialData.load_materials()
|
||||
if obj.BIMMaterialProperties.ifc_style_id:
|
||||
IfcStore.get_file().by_id(obj.BIMMaterialProperties.ifc_style_id).Name = obj.name
|
||||
refresh_ui_data()
|
||||
@@ -76,46 +72,87 @@ def name_callback(obj, data):
|
||||
if not obj.BIMObjectProperties.ifc_definition_id or "/" not in obj.name:
|
||||
return
|
||||
element = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
if element.is_a("IfcGridAxis"):
|
||||
element.AxisTag = obj.name.split("/")[1]
|
||||
refresh_ui_data()
|
||||
if not element.is_a("IfcRoot"):
|
||||
return
|
||||
if element.is_a("IfcSpatialStructureElement") or (hasattr(element, "IsDecomposedBy") and element.IsDecomposedBy):
|
||||
collection = obj.users_collection[0]
|
||||
collection.name = obj.name
|
||||
if element.is_a("IfcGrid"):
|
||||
axis_obj = IfcStore.get_element(element.UAxes[0].id())
|
||||
axis_collection = axis_obj.users_collection[0]
|
||||
grid_collection = None
|
||||
for collection in bpy.data.collections:
|
||||
if axis_collection.name in collection.children.keys():
|
||||
grid_collection = collection
|
||||
break
|
||||
if grid_collection:
|
||||
grid_collection.name = obj.name
|
||||
if element.is_a("IfcTypeProduct"):
|
||||
TypeData.purge()
|
||||
if obj.BIMObjectProperties.collection:
|
||||
obj.BIMObjectProperties.collection.name = obj.name
|
||||
element.Name = "/".join(obj.name.split("/")[1:])
|
||||
refresh_ui_data()
|
||||
|
||||
|
||||
def color_callback(obj, data):
|
||||
if obj.BIMMaterialProperties.ifc_style_id:
|
||||
IfcStore.edited_objs.add(obj)
|
||||
tool.Ifc.edit(obj)
|
||||
|
||||
|
||||
def active_object_callback():
|
||||
refresh_ui_data()
|
||||
update_bim_tool_props()
|
||||
|
||||
|
||||
def subscribe_to(object, data_path, callback):
|
||||
def update_bim_tool_props():
|
||||
"""update BIM Tools props (such as extrusion_depth, length and x_angle) when active object changes"""
|
||||
obj = bpy.context.active_object
|
||||
|
||||
# bunch of checks to see if we're in a valid state
|
||||
if not obj:
|
||||
return
|
||||
mode = bpy.context.mode
|
||||
current_tool = bpy.context.workspace.tools.from_space_view3d_mode(mode)
|
||||
if not current_tool or current_tool.idname != "bim.bim_tool":
|
||||
return
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
return
|
||||
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
||||
if not representation:
|
||||
return
|
||||
extrusion = tool.Model.get_extrusion(representation)
|
||||
if not extrusion:
|
||||
return
|
||||
|
||||
def get_x_angle(extrusion):
|
||||
x, y, z = extrusion.ExtrudedDirection.DirectionRatios
|
||||
x_angle = Vector((0, 1)).angle_signed(Vector((y, z)))
|
||||
return x_angle
|
||||
|
||||
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
props = bpy.context.scene.BIMModelProperties
|
||||
if not AuthoringData.is_loaded:
|
||||
AuthoringData.load()
|
||||
|
||||
if AuthoringData.data["active_material_usage"] == "LAYER2":
|
||||
x_angle = get_x_angle(extrusion)
|
||||
axis = tool.Model.get_wall_axis(obj)["reference"]
|
||||
props.extrusion_depth = extrusion.Depth * si_conversion * cos(x_angle)
|
||||
props.length = (axis[1] - axis[0]).length
|
||||
props.x_angle = x_angle
|
||||
|
||||
elif AuthoringData.data["active_material_usage"] == "LAYER3":
|
||||
x_angle = get_x_angle(extrusion)
|
||||
props.x_angle = x_angle
|
||||
|
||||
elif AuthoringData.data["active_material_usage"] == "PROFILE":
|
||||
props.extrusion_depth = extrusion.Depth * si_conversion
|
||||
|
||||
|
||||
def active_material_index_callback(obj, data):
|
||||
refresh_ui_data()
|
||||
|
||||
|
||||
def subscribe_to(obj, data_path, callback):
|
||||
try:
|
||||
subscribe_to = object.path_resolve(data_path, False)
|
||||
subscribe_to = obj.path_resolve(data_path, False)
|
||||
except:
|
||||
return
|
||||
bpy.msgbus.subscribe_rna(
|
||||
key=subscribe_to,
|
||||
owner=object,
|
||||
owner=obj,
|
||||
args=(
|
||||
object,
|
||||
obj,
|
||||
data_path,
|
||||
),
|
||||
notify=callback,
|
||||
@@ -134,6 +171,9 @@ def refresh_ui_data():
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if isinstance(tool.Ifc.get(), ifcopenshell.sqlite):
|
||||
tool.Ifc.get().clear_cache()
|
||||
|
||||
|
||||
def purge_module_data():
|
||||
from blenderbim.bim import modules
|
||||
@@ -225,6 +265,12 @@ def get_application_version():
|
||||
)
|
||||
|
||||
|
||||
def viewport_shading_changed_callback(area):
|
||||
shading = area.spaces.active.shading.type
|
||||
if shading == "RENDERED":
|
||||
bpy.context.scene.BIMStylesProperties.active_style_type = "External"
|
||||
|
||||
|
||||
@persistent
|
||||
def setDefaultProperties(scene):
|
||||
global global_subscription_owner
|
||||
@@ -232,74 +278,21 @@ def setDefaultProperties(scene):
|
||||
bpy.msgbus.subscribe_rna(
|
||||
key=active_object_key, owner=global_subscription_owner, args=(), notify=active_object_callback
|
||||
)
|
||||
|
||||
# subscribe to changes in viewport shading mode
|
||||
# NOTE: couldn't find a way to make it work for new areas too
|
||||
# it starts working for them after blender restart though
|
||||
for screen in bpy.data.screens:
|
||||
for area in screen.areas:
|
||||
if area.type != "VIEW_3D":
|
||||
continue
|
||||
shading = area.spaces.active.shading
|
||||
key = shading.path_resolve("type", False)
|
||||
|
||||
bpy.msgbus.subscribe_rna(
|
||||
key=key, owner=global_subscription_owner, args=(area,), notify=viewport_shading_changed_callback
|
||||
)
|
||||
|
||||
ifcopenshell.api.owner.settings.get_user = lambda ifc: core_owner.get_user(tool.Owner)
|
||||
ifcopenshell.api.owner.settings.get_application = get_application
|
||||
# TODO: Move to drawing module
|
||||
if len(bpy.context.scene.DocProperties.drawing_styles) == 0:
|
||||
drawing_style = bpy.context.scene.DocProperties.drawing_styles.add()
|
||||
drawing_style.name = "Technical"
|
||||
drawing_style.render_type = "VIEWPORT"
|
||||
drawing_style.raster_style = json.dumps(
|
||||
{
|
||||
RasterStyleProperty.WORLD_COLOR.value: (1, 1, 1),
|
||||
RasterStyleProperty.RENDER_ENGINE.value: "BLENDER_WORKBENCH",
|
||||
RasterStyleProperty.RENDER_TRANSPARENT.value: False,
|
||||
RasterStyleProperty.SHADING_SHOW_OBJECT_OUTLINE.value: True,
|
||||
RasterStyleProperty.SHADING_SHOW_CAVITY.value: False,
|
||||
RasterStyleProperty.SHADING_CAVITY_TYPE.value: "BOTH",
|
||||
RasterStyleProperty.SHADING_CURVATURE_RIDGE_FACTOR.value: 1,
|
||||
RasterStyleProperty.SHADING_CURVATURE_VALLEY_FACTOR.value: 1,
|
||||
RasterStyleProperty.VIEW_TRANSFORM.value: "Standard",
|
||||
RasterStyleProperty.SHADING_LIGHT.value: "FLAT",
|
||||
RasterStyleProperty.SHADING_COLOR_TYPE.value: "SINGLE",
|
||||
RasterStyleProperty.SHADING_SINGLE_COLOR.value: (1, 1, 1),
|
||||
RasterStyleProperty.SHADING_SHOW_SHADOWS.value: False,
|
||||
RasterStyleProperty.SHADING_SHADOW_INTENSITY.value: 0.5,
|
||||
RasterStyleProperty.DISPLAY_LIGHT_DIRECTION.value: (0.5, 0.5, 0.5),
|
||||
RasterStyleProperty.VIEW_USE_CURVE_MAPPING.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_WIREFRAMES.value: True,
|
||||
RasterStyleProperty.OVERLAY_WIREFRAME_THRESHOLD.value: 0,
|
||||
RasterStyleProperty.OVERLAY_SHOW_FLOOR.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_AXIS_X.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_AXIS_Y.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_AXIS_Z.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_OBJECT_ORIGINS.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_RELATIONSHIP_LINES.value: False,
|
||||
}
|
||||
)
|
||||
drawing_style = bpy.context.scene.DocProperties.drawing_styles.add()
|
||||
drawing_style.name = "Shaded"
|
||||
drawing_style.render_type = "VIEWPORT"
|
||||
drawing_style.raster_style = json.dumps(
|
||||
{
|
||||
RasterStyleProperty.WORLD_COLOR.value: (1, 1, 1),
|
||||
RasterStyleProperty.RENDER_ENGINE.value: "BLENDER_WORKBENCH",
|
||||
RasterStyleProperty.RENDER_TRANSPARENT.value: False,
|
||||
RasterStyleProperty.SHADING_SHOW_OBJECT_OUTLINE.value: True,
|
||||
RasterStyleProperty.SHADING_SHOW_CAVITY.value: True,
|
||||
RasterStyleProperty.SHADING_CAVITY_TYPE.value: "BOTH",
|
||||
RasterStyleProperty.SHADING_CURVATURE_RIDGE_FACTOR.value: 1,
|
||||
RasterStyleProperty.SHADING_CURVATURE_VALLEY_FACTOR.value: 1,
|
||||
RasterStyleProperty.VIEW_TRANSFORM.value: "Standard",
|
||||
RasterStyleProperty.SHADING_LIGHT.value: "STUDIO",
|
||||
RasterStyleProperty.SHADING_COLOR_TYPE.value: "MATERIAL",
|
||||
RasterStyleProperty.SHADING_SINGLE_COLOR.value: (1, 1, 1),
|
||||
RasterStyleProperty.SHADING_SHOW_SHADOWS.value: True,
|
||||
RasterStyleProperty.SHADING_SHADOW_INTENSITY.value: 0.5,
|
||||
RasterStyleProperty.DISPLAY_LIGHT_DIRECTION.value: (0.5, 0.5, 0.5),
|
||||
RasterStyleProperty.VIEW_USE_CURVE_MAPPING.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_WIREFRAMES.value: False,
|
||||
RasterStyleProperty.OVERLAY_WIREFRAME_THRESHOLD.value: 0,
|
||||
RasterStyleProperty.OVERLAY_SHOW_FLOOR.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_AXIS_X.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_AXIS_Y.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_AXIS_Z.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_OBJECT_ORIGINS.value: False,
|
||||
RasterStyleProperty.OVERLAY_SHOW_RELATIONSHIP_LINES.value: False,
|
||||
}
|
||||
)
|
||||
drawing_style = bpy.context.scene.DocProperties.drawing_styles.add()
|
||||
drawing_style.name = "Blender Default"
|
||||
drawing_style.render_type = "DEFAULT"
|
||||
bpy.ops.bim.save_drawing_style(index="2")
|
||||
AuthoringData.type_thumbnails = {}
|
||||
AuthoringData.type_thumbnails = {}
|
||||
|
||||
@@ -23,6 +23,7 @@ import math
|
||||
import zipfile
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.attribute
|
||||
import ifcopenshell.util.element
|
||||
from ifcopenshell.util.doc import get_attribute_doc, get_predefined_type_doc, get_property_doc
|
||||
from mathutils import geometry
|
||||
from mathutils import Vector
|
||||
@@ -30,9 +31,15 @@ import blenderbim.tool as tool
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
|
||||
def draw_attributes(props, layout, copy_operator=None):
|
||||
def draw_attributes(props, layout, copy_operator=None, popup_active_attribute=None):
|
||||
"""you can set attribute active in popup with `active_attribute`
|
||||
meaning you will be able to type into attribute's field without having to click
|
||||
on it first
|
||||
"""
|
||||
for attribute in props:
|
||||
row = layout.row(align=True)
|
||||
if attribute == popup_active_attribute:
|
||||
row.activate_init = True
|
||||
draw_attribute(attribute, row, copy_operator)
|
||||
|
||||
|
||||
@@ -43,25 +50,34 @@ def draw_attribute(attribute, layout, copy_operator=None):
|
||||
return
|
||||
if value_name == "enum_value":
|
||||
prop_with_search(layout, attribute, "enum_value", text=attribute.name)
|
||||
elif attribute.name in ["ScheduleDuration", "ActualDuration", "FreeFloat", "TotalFloat"]:
|
||||
propis = bpy.context.scene.BIMWorkScheduleProperties
|
||||
for item in propis.durations_attributes:
|
||||
if item.name == attribute.name:
|
||||
duration_props = item
|
||||
layout.label(text=attribute.name)
|
||||
layout.prop(duration_props, "years", text="Y")
|
||||
layout.prop(duration_props, "months", text="M")
|
||||
layout.prop(duration_props, "days", text="D")
|
||||
layout.prop(duration_props, "hours", text="H")
|
||||
layout.prop(duration_props, "minutes", text="Min")
|
||||
layout.prop(duration_props, "seconds", text="S")
|
||||
break
|
||||
else:
|
||||
layout.prop(
|
||||
attribute,
|
||||
value_name,
|
||||
text=attribute.name,
|
||||
)
|
||||
if "ScheduleDuration" in attribute.name:
|
||||
layout.prop(bpy.context.scene.BIMDuration, "duration_days", text="D")
|
||||
layout.prop(bpy.context.scene.BIMDuration, "duration_hours", text="H")
|
||||
layout.prop(bpy.context.scene.BIMDuration, "duration_minutes", text="M")
|
||||
|
||||
if attribute.is_uri:
|
||||
op = layout.operator("bim.select_uri_attribute", text="", icon="FILE_FOLDER")
|
||||
op.data_path = attribute.path_from_id("string_value")
|
||||
if attribute.is_optional:
|
||||
layout.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
|
||||
if copy_operator:
|
||||
op = layout.operator(f"{copy_operator}", text="", icon="COPYDOWN")
|
||||
op.name = attribute.name
|
||||
if attribute.is_uri:
|
||||
op = layout.operator("bim.select_uri_attribute", text="", icon="FILE_FOLDER")
|
||||
op.data_path = attribute.path_from_id("string_value")
|
||||
|
||||
|
||||
def import_attributes(ifc_class, props, data, callback=None):
|
||||
@@ -198,6 +214,12 @@ def get_obj_ifc_definition_id(context, obj, obj_type):
|
||||
return bpy.data.objects.get(obj).BIMObjectProperties.ifc_definition_id
|
||||
elif obj_type == "Material":
|
||||
return bpy.data.materials.get(obj).BIMObjectProperties.ifc_definition_id
|
||||
elif obj_type == "MaterialSet":
|
||||
return ifcopenshell.util.element.get_material(
|
||||
tool.Ifc.get_entity(bpy.data.objects.get(obj)), should_skip_usage=True
|
||||
).id()
|
||||
elif obj_type == "MaterialSetItem":
|
||||
return bpy.data.objects.get(obj).BIMObjectMaterialProperties.active_material_set_item_id
|
||||
elif obj_type == "Task":
|
||||
return context.scene.BIMTaskTreeProperties.tasks[
|
||||
context.scene.BIMWorkScheduleProperties.active_task_index
|
||||
@@ -227,6 +249,33 @@ def close_operator_panel(event):
|
||||
bpy.app.timers.register(move_back, first_interval=0.01)
|
||||
|
||||
|
||||
def convert_property_group_from_si(property_group, skip_props=()):
|
||||
"""Method converts property group values from si to current ifc project units
|
||||
|
||||
based on default values of the properties.
|
||||
|
||||
List of properties to skip can be supplied in `skip_props`."""
|
||||
conversion_k = 1.0 / ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
skip_props = ("rna_type", "name") + skip_props
|
||||
for prop_name in property_group.bl_rna.properties.keys():
|
||||
if prop_name in skip_props:
|
||||
continue
|
||||
prop_bl_rna = property_group.bl_rna.properties[prop_name]
|
||||
if prop_bl_rna.array_length > 0:
|
||||
prop_value = prop_bl_rna.default_array
|
||||
else:
|
||||
prop_value = prop_bl_rna.default
|
||||
|
||||
if type(prop_value) is float:
|
||||
prop_value = prop_value * conversion_k
|
||||
elif type(prop_value) is bpy.types.bpy_prop_array:
|
||||
prop_value = [el * conversion_k for el in prop_value]
|
||||
setattr(property_group, prop_name, prop_value)
|
||||
|
||||
|
||||
# TODO this should move into ifcopenshell.util
|
||||
|
||||
|
||||
class IfcHeaderExtractor:
|
||||
def __init__(self, filepath: str):
|
||||
self.filepath = filepath
|
||||
@@ -238,6 +287,8 @@ class IfcHeaderExtractor:
|
||||
return self.extract_ifc_spf(ifc_file)
|
||||
elif extension.lower() == "ifczip":
|
||||
return self.extract_ifc_zip()
|
||||
elif extension.lower() == "ifcsqlite":
|
||||
return {} # TODO
|
||||
|
||||
def extract_ifc_spf(self, ifc_file):
|
||||
# https://www.steptools.com/stds/step/IS_final_p21e3.html#clause-8
|
||||
|
||||
@@ -24,6 +24,7 @@ import zipfile
|
||||
import tempfile
|
||||
import ifcopenshell
|
||||
import blenderbim.bim.handler
|
||||
import blenderbim.tool as tool
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -35,7 +36,6 @@ class IfcStore:
|
||||
cache_path = None
|
||||
id_map = {}
|
||||
guid_map = {}
|
||||
deleted_ids = set()
|
||||
edited_objs = set()
|
||||
pset_template_path = ""
|
||||
pset_template_file = None
|
||||
@@ -51,6 +51,7 @@ class IfcStore:
|
||||
history = []
|
||||
future = []
|
||||
schema_identifiers = ["IFC4", "IFC2X3", "IFC4X3"]
|
||||
session_files = {}
|
||||
|
||||
@staticmethod
|
||||
def purge():
|
||||
@@ -61,7 +62,6 @@ class IfcStore:
|
||||
IfcStore.cache_path = None
|
||||
IfcStore.id_map = {}
|
||||
IfcStore.guid_map = {}
|
||||
IfcStore.deleted_ids = set()
|
||||
IfcStore.edited_objs = set()
|
||||
IfcStore.pset_template_path = ""
|
||||
IfcStore.pset_template_file = None
|
||||
@@ -71,6 +71,7 @@ class IfcStore:
|
||||
IfcStore.history = []
|
||||
IfcStore.future = []
|
||||
IfcStore.schema_identifiers = ["IFC4", "IFC2X3", "IFC4X3"]
|
||||
IfcStore.session_files = {}
|
||||
|
||||
@staticmethod
|
||||
def get_file():
|
||||
@@ -96,7 +97,14 @@ class IfcStore:
|
||||
try:
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(IfcStore.cache_path, cache_settings)
|
||||
except:
|
||||
return
|
||||
if os.path.exists(IfcStore.cache_path):
|
||||
os.remove(IfcStore.cache_path)
|
||||
try:
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(IfcStore.cache_path, cache_settings)
|
||||
except:
|
||||
return
|
||||
else:
|
||||
return
|
||||
return IfcStore.cache
|
||||
|
||||
@staticmethod
|
||||
@@ -112,6 +120,8 @@ class IfcStore:
|
||||
|
||||
@staticmethod
|
||||
def load_file(path):
|
||||
if not os.path.isfile(path):
|
||||
return
|
||||
extension = path.split(".")[-1]
|
||||
if extension.lower() == "ifczip":
|
||||
with tempfile.TemporaryDirectory() as unzipped_path:
|
||||
@@ -122,7 +132,9 @@ class IfcStore:
|
||||
return
|
||||
elif extension.lower() == "ifcxml":
|
||||
IfcStore.file = ifcopenshell.file(ifcopenshell.ifcopenshell_wrapper.parse_ifcxml(path))
|
||||
elif extension.lower() == "ifc":
|
||||
elif bpy.context.scene.BIMProjectProperties.should_stream:
|
||||
IfcStore.file = ifcopenshell.open(path, should_stream=True)
|
||||
else:
|
||||
IfcStore.file = ifcopenshell.open(path)
|
||||
|
||||
@staticmethod
|
||||
@@ -268,23 +280,6 @@ class IfcStore:
|
||||
data = {"id": element.id(), "obj": obj.name}
|
||||
IfcStore.commit_link_element(data)
|
||||
|
||||
@staticmethod
|
||||
def delete_element(element):
|
||||
IfcStore.deleted_ids.add(element.id())
|
||||
if IfcStore.history:
|
||||
data = {"id": element.id()}
|
||||
IfcStore.history[-1]["operations"].append(
|
||||
{"rollback": IfcStore.rollback_delete_element, "commit": IfcStore.commit_delete_element, "data": data}
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def rollback_delete_element(data):
|
||||
IfcStore.deleted_ids.remove(data["id"])
|
||||
|
||||
@staticmethod
|
||||
def commit_delete_element(data):
|
||||
IfcStore.deleted_ids.add(data["id"])
|
||||
|
||||
@staticmethod
|
||||
def link_element(element, obj):
|
||||
existing_obj = IfcStore.id_map.get(element.id(), None)
|
||||
@@ -311,6 +306,7 @@ class IfcStore:
|
||||
blenderbim.bim.handler.subscribe_to(obj, "diffuse_color", blenderbim.bim.handler.color_callback)
|
||||
elif isinstance(obj, bpy.types.Object):
|
||||
blenderbim.bim.handler.subscribe_to(obj, "mode", blenderbim.bim.handler.mode_callback)
|
||||
blenderbim.bim.handler.subscribe_to(obj, "active_material_index", blenderbim.bim.handler.active_material_index_callback)
|
||||
|
||||
for listener in IfcStore.element_listeners:
|
||||
listener(element, obj)
|
||||
@@ -361,7 +357,7 @@ class IfcStore:
|
||||
def unlink_element(element=None, obj=None):
|
||||
if element is None:
|
||||
try:
|
||||
element = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import ifcopenshell.util.geolocation
|
||||
import blenderbim.tool as tool
|
||||
from itertools import chain, accumulate
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.drawing.prop import get_diagram_scales
|
||||
from blenderbim.bim.module.drawing.prop import ANNOTATION_TYPES_DATA
|
||||
|
||||
|
||||
class FileCopy(threading.Thread):
|
||||
@@ -60,7 +60,6 @@ class MaterialCreator:
|
||||
|
||||
def create(self, element, obj, mesh):
|
||||
self.mesh = mesh
|
||||
self.obj = obj
|
||||
if (hasattr(element, "Representation") and not element.Representation) or (
|
||||
hasattr(element, "RepresentationMaps") and not element.RepresentationMaps
|
||||
):
|
||||
@@ -140,11 +139,11 @@ class MaterialCreator:
|
||||
def assign_material_slots_to_faces(self):
|
||||
if "ios_materials" not in self.mesh or not self.mesh["ios_materials"]:
|
||||
return
|
||||
if len(self.obj.material_slots) == 1:
|
||||
if len(self.mesh.materials) == 1:
|
||||
return
|
||||
material_to_slot = {}
|
||||
for i, material in enumerate(self.mesh["ios_materials"]):
|
||||
slot_index = self.obj.material_slots.find(self.styles[material].name)
|
||||
slot_index = self.mesh.materials.find(self.styles[material].name)
|
||||
material_to_slot[i] = slot_index
|
||||
|
||||
if len(self.mesh.polygons) == len(self.mesh["ios_material_ids"]):
|
||||
@@ -179,11 +178,16 @@ class IfcImporter:
|
||||
self.settings.set_deflection_tolerance(self.ifc_import_settings.deflection_tolerance)
|
||||
self.settings.set_angular_tolerance(self.ifc_import_settings.angular_tolerance)
|
||||
self.settings.set(self.settings.STRICT_TOLERANCE, True)
|
||||
self.settings_curve = ifcopenshell.geom.settings()
|
||||
self.settings_curve.set_deflection_tolerance(self.ifc_import_settings.deflection_tolerance)
|
||||
self.settings_curve.set_angular_tolerance(self.ifc_import_settings.angular_tolerance)
|
||||
self.settings_curve.set(self.settings_curve.STRICT_TOLERANCE, True)
|
||||
self.settings_curve.set(self.settings_curve.INCLUDE_CURVES, True)
|
||||
self.settings_native = ifcopenshell.geom.settings()
|
||||
self.settings_native.set(self.settings_native.INCLUDE_CURVES, True)
|
||||
self.settings_2d = ifcopenshell.geom.settings()
|
||||
self.settings_2d.set(self.settings_2d.INCLUDE_CURVES, True)
|
||||
self.settings_2d.set(self.settings.STRICT_TOLERANCE, True)
|
||||
self.settings_2d.set(self.settings_2d.STRICT_TOLERANCE, True)
|
||||
self.project = None
|
||||
self.has_existing_project = False
|
||||
self.collections = {}
|
||||
@@ -236,14 +240,14 @@ class IfcImporter:
|
||||
self.profile_code("Create materials")
|
||||
self.create_styles()
|
||||
self.profile_code("Create styles")
|
||||
self.create_annotations()
|
||||
self.profile_code("Create annotation")
|
||||
self.parse_native_elements()
|
||||
self.profile_code("Parsing native elements")
|
||||
self.create_native_elements()
|
||||
self.profile_code("Create native elements")
|
||||
self.create_elements()
|
||||
self.profile_code("Create elements")
|
||||
self.create_generic_elements(self.annotations)
|
||||
self.profile_code("Create annotations")
|
||||
self.create_grids()
|
||||
self.profile_code("Create grids")
|
||||
self.create_spatial_elements()
|
||||
@@ -304,12 +308,12 @@ class IfcImporter:
|
||||
)
|
||||
if self.body_contexts:
|
||||
self.settings.set_context_ids(self.body_contexts)
|
||||
# Annotation is to accommodate broken Revit files
|
||||
# Annotation ContextType is to accommodate broken Revit files
|
||||
# See https://github.com/Autodesk/revit-ifc/issues/187
|
||||
self.plan_contexts = [
|
||||
c.id()
|
||||
for c in self.file.by_type("IfcGeometricRepresentationContext")
|
||||
if c.ContextType in ["Plan", "Annotation"]
|
||||
if c.ContextType in ["Plan", "Annotation"] or c.ContextIdentifier == "Annotation"
|
||||
]
|
||||
if self.plan_contexts:
|
||||
self.settings_2d.set_context_ids(self.plan_contexts)
|
||||
@@ -323,10 +327,13 @@ class IfcImporter:
|
||||
if isinstance(self.elements, set):
|
||||
self.elements = list(self.elements)
|
||||
# TODO: enable filtering for annotations
|
||||
self.annotations = set(self.file.by_type("IfcAnnotation"))
|
||||
self.annotations = set([a for a in self.file.by_type("IfcAnnotation") if not a.HasAssignments])
|
||||
else:
|
||||
self.elements = self.file.by_type("IfcElement")
|
||||
self.annotations = set(self.file.by_type("IfcAnnotation"))
|
||||
if self.file.schema in ("IFC2X3", "IFC4"):
|
||||
self.elements = self.file.by_type("IfcElement") + self.file.by_type("IfcProxy")
|
||||
else:
|
||||
self.elements = self.file.by_type("IfcElement")
|
||||
self.annotations = set([a for a in self.file.by_type("IfcAnnotation") if not a.HasAssignments])
|
||||
|
||||
self.elements = [e for e in self.elements if not e.is_a("IfcFeatureElement")]
|
||||
if self.ifc_import_settings.is_coordinating:
|
||||
@@ -337,17 +344,11 @@ class IfcImporter:
|
||||
if self.ifc_import_settings.has_filter or offset or offset_limit < len(self.elements):
|
||||
self.element_types = set([ifcopenshell.util.element.get_type(e) for e in self.elements])
|
||||
else:
|
||||
if self.file.schema in ("IFC2X3", "IFC4"):
|
||||
self.element_types = set(
|
||||
self.file.by_type("IfcElementType")
|
||||
+ self.file.by_type("IfcDoorStyle")
|
||||
+ self.file.by_type("IfcWindowStyle")
|
||||
)
|
||||
else:
|
||||
self.element_types = set(self.file.by_type("IfcElementType"))
|
||||
self.element_types = set(self.file.by_type("IfcTypeProduct"))
|
||||
|
||||
if self.ifc_import_settings.has_filter and self.ifc_import_settings.should_filter_spatial_elements:
|
||||
self.spatial_elements = self.get_spatial_elements_filtered_by_elements(self.elements)
|
||||
filtered_elements = self.elements | set(self.file.by_type("IfcGrid"))
|
||||
self.spatial_elements = self.get_spatial_elements_filtered_by_elements(filtered_elements)
|
||||
else:
|
||||
if self.file.schema == "IFC2X3":
|
||||
self.spatial_elements = set(self.file.by_type("IfcSpatialStructureElement"))
|
||||
@@ -361,11 +362,13 @@ class IfcImporter:
|
||||
while True:
|
||||
results.add(spatial_element)
|
||||
spatial_element = ifcopenshell.util.element.get_aggregate(spatial_element)
|
||||
if not spatial_element or spatial_element.is_a("IfcContext"):
|
||||
if not spatial_element or spatial_element.is_a() in ("IfcProject", "IfcProjectLibrary"):
|
||||
break
|
||||
return results
|
||||
|
||||
def parse_native_elements(self):
|
||||
if not self.ifc_import_settings.should_load_geometry:
|
||||
return
|
||||
for element in self.elements:
|
||||
if self.is_native(element):
|
||||
self.native_elements.add(element)
|
||||
@@ -381,7 +384,7 @@ class IfcImporter:
|
||||
representations = self.get_transformed_body_representations(element.Representation.Representations)
|
||||
|
||||
# Single swept disk solids (e.g. rebar) are better natively represented as beveled curves
|
||||
if self.is_native_swept_disk_solid(representations):
|
||||
if self.is_native_swept_disk_solid(element, representations):
|
||||
self.native_data[element.GlobalId] = {
|
||||
"representations": representations,
|
||||
"representation": self.get_body_representation(element.Representation.Representations),
|
||||
@@ -409,16 +412,20 @@ class IfcImporter:
|
||||
}
|
||||
return True
|
||||
|
||||
def is_native_swept_disk_solid(self, representations):
|
||||
def is_native_swept_disk_solid(self, element, representations):
|
||||
for representation in representations:
|
||||
items = representation["raw"].Items or [] # Be forgiving of invalid IFCs because Revit :(
|
||||
if len(items) == 1 and items[0].is_a("IfcSweptDiskSolid"):
|
||||
if tool.Pset.get_element_pset(element, "BBIM_Railing"):
|
||||
return False
|
||||
return True
|
||||
elif len(items) and ( # See #2508 why we accommodate for invalid IFCs here
|
||||
elif len(items) and ( # See #2508 why we accommodate for invalid IFCs here
|
||||
items[0].is_a("IfcSweptDiskSolid")
|
||||
and len({i.is_a() for i in items}) == 1
|
||||
and len({i.Radius for i in items}) == 1
|
||||
):
|
||||
if tool.Pset.get_element_pset(element, "BBIM_Railing"):
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -573,6 +580,8 @@ class IfcImporter:
|
||||
return result
|
||||
|
||||
def create_grids(self):
|
||||
if not self.ifc_import_settings.should_load_geometry:
|
||||
return
|
||||
grids = self.file.by_type("IfcGrid")
|
||||
for grid in grids:
|
||||
shape = None
|
||||
@@ -586,7 +595,7 @@ class IfcImporter:
|
||||
if bpy.context.preferences.addons["blenderbim"].preferences.lock_grids_on_import:
|
||||
grid_obj.lock_location = (True, True, True)
|
||||
grid_obj.lock_rotation = (True, True, True)
|
||||
collection = bpy.data.collections.new(self.get_name(grid))
|
||||
collection = bpy.data.collections.new(tool.Loader.get_name(grid))
|
||||
u_axes = bpy.data.collections.new("UAxes")
|
||||
collection.children.link(u_axes)
|
||||
v_axes = bpy.data.collections.new("VAxes")
|
||||
@@ -618,38 +627,37 @@ class IfcImporter:
|
||||
|
||||
def create_element_type(self, element):
|
||||
self.ifc_import_settings.logger.info("Creating object %s", element)
|
||||
representation_map = self.get_type_product_body_representation_map(element)
|
||||
mesh = None
|
||||
if representation_map:
|
||||
representation = representation_map.MappedRepresentation
|
||||
mesh_name = "{}/{}".format(representation.ContextOfItems.id(), representation.id())
|
||||
mesh = self.meshes.get(mesh_name)
|
||||
if mesh is None:
|
||||
try:
|
||||
shape = ifcopenshell.geom.create_shape(self.settings, representation_map.MappedRepresentation)
|
||||
mesh = self.create_mesh(element, shape)
|
||||
self.link_mesh(shape, mesh)
|
||||
self.meshes[mesh_name] = mesh
|
||||
except:
|
||||
self.ifc_import_settings.logger.error("Failed to generate shape for %s", element)
|
||||
obj = bpy.data.objects.new(self.get_name(element), mesh)
|
||||
if self.ifc_import_settings.should_load_geometry:
|
||||
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
||||
if not representation:
|
||||
representation = ifcopenshell.util.representation.get_representation(element, "Plan", "Annotation")
|
||||
if not representation:
|
||||
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Annotation")
|
||||
if representation:
|
||||
mesh_name = "{}/{}".format(representation.ContextOfItems.id(), representation.id())
|
||||
mesh = self.meshes.get(mesh_name)
|
||||
if mesh is None:
|
||||
shape = None
|
||||
try:
|
||||
shape = ifcopenshell.geom.create_shape(self.settings, representation)
|
||||
except:
|
||||
try:
|
||||
shape = ifcopenshell.geom.create_shape(self.settings_2d, representation)
|
||||
except:
|
||||
self.ifc_import_settings.logger.error("Failed to generate shape for %s", element)
|
||||
if shape:
|
||||
mesh = self.create_mesh(element, shape)
|
||||
tool.Loader.link_mesh(shape, mesh)
|
||||
self.meshes[mesh_name] = mesh
|
||||
obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh)
|
||||
self.link_element(element, obj)
|
||||
self.material_creator.create(element, obj, mesh)
|
||||
self.type_products[element.GlobalId] = obj
|
||||
|
||||
def get_type_product_body_representation_map(self, element):
|
||||
if not element.RepresentationMaps:
|
||||
return
|
||||
for representation_map in element.RepresentationMaps:
|
||||
context = representation_map.MappedRepresentation.ContextOfItems
|
||||
if (
|
||||
context.ContextType == "Model"
|
||||
and context.ContextIdentifier == "Body"
|
||||
and context.TargetView == "MODEL_VIEW"
|
||||
):
|
||||
return representation_map
|
||||
|
||||
def create_native_elements(self):
|
||||
if not self.ifc_import_settings.should_load_geometry:
|
||||
return
|
||||
progress = 0
|
||||
checkpoint = time.time()
|
||||
total = len(self.native_elements)
|
||||
@@ -687,36 +695,91 @@ class IfcImporter:
|
||||
def create_spatial_elements(self):
|
||||
self.create_generic_elements(self.spatial_elements)
|
||||
|
||||
def create_annotations(self):
|
||||
self.create_generic_elements(self.annotations)
|
||||
|
||||
def create_elements(self):
|
||||
self.create_generic_elements(self.elements)
|
||||
|
||||
def create_generic_elements(self, elements):
|
||||
if isinstance(self.file, ifcopenshell.sqlite):
|
||||
return self.create_generic_sqlite_elements(elements)
|
||||
|
||||
# Based on my experience in viewing BIM models, representations are prioritised as follows:
|
||||
# 1. 3D Body, 2. 2D Plans, 3. Point clouds, 4. No representation
|
||||
# If an element has a representation that doesn't follow 1, 2, or 3, it will not show by default.
|
||||
# 1. 3D Body, 2. 2D Body, 3. 2D Plans / annotations, 4. Point clouds, 5. No representation
|
||||
# If an element has a representation that doesn't follow 1, 2, 3, or 4, it will not show by default.
|
||||
# The user can load them later if they want to view them.
|
||||
products = self.create_products(elements)
|
||||
elements -= products
|
||||
products = self.create_curve_products(elements)
|
||||
elements -= products
|
||||
products = self.create_pointclouds(elements)
|
||||
elements -= products
|
||||
for element in elements:
|
||||
if self.ifc_import_settings.should_load_geometry:
|
||||
products = self.create_products(elements)
|
||||
elements -= products
|
||||
products = self.create_products(elements, settings=self.settings_curve)
|
||||
elements -= products
|
||||
products = self.create_products(elements, settings=self.settings_2d)
|
||||
elements -= products
|
||||
products = self.create_pointclouds(elements)
|
||||
elements -= products
|
||||
|
||||
total = len(elements)
|
||||
for i, element in enumerate(elements):
|
||||
if i % 250 == 0:
|
||||
print("{} / {} elements processed ...".format(i, total))
|
||||
self.create_product(element)
|
||||
|
||||
def create_products(self, products):
|
||||
def create_generic_sqlite_elements(self, elements):
|
||||
self.geometry_cache = self.file.get_geometry([e.id() for e in elements])
|
||||
for geometry_id, geometry in self.geometry_cache["geometry"].items():
|
||||
mesh_name = tool.Loader.get_mesh_name(type("Geometry", (), {"id": geometry_id}))
|
||||
mesh = bpy.data.meshes.new(mesh_name)
|
||||
|
||||
verts = geometry["verts"]
|
||||
mesh["has_cartesian_point_offset"] = False
|
||||
|
||||
if geometry["faces"]:
|
||||
num_vertices = len(verts) // 3
|
||||
total_faces = len(geometry["faces"])
|
||||
loop_start = range(0, total_faces, 3)
|
||||
num_loops = total_faces // 3
|
||||
loop_total = [3] * num_loops
|
||||
num_vertex_indices = len(geometry["faces"])
|
||||
|
||||
mesh.vertices.add(num_vertices)
|
||||
mesh.vertices.foreach_set("co", verts)
|
||||
mesh.loops.add(num_vertex_indices)
|
||||
mesh.loops.foreach_set("vertex_index", geometry["faces"])
|
||||
mesh.polygons.add(num_loops)
|
||||
mesh.polygons.foreach_set("loop_start", loop_start)
|
||||
mesh.polygons.foreach_set("loop_total", loop_total)
|
||||
mesh.update()
|
||||
else:
|
||||
e = geometry["edges"]
|
||||
v = verts
|
||||
vertices = [[v[i], v[i + 1], v[i + 2]] for i in range(0, len(v), 3)]
|
||||
edges = [[e[i], e[i + 1]] for i in range(0, len(e), 2)]
|
||||
mesh.from_pydata(vertices, edges, [])
|
||||
|
||||
mesh["ios_materials"] = geometry["materials"]
|
||||
mesh["ios_material_ids"] = geometry["material_ids"]
|
||||
self.meshes[mesh_name] = mesh
|
||||
|
||||
total = len(elements)
|
||||
for i, element in enumerate(elements):
|
||||
if i % 250 == 0:
|
||||
print("{} / {} elements processed ...".format(i, total))
|
||||
mesh = None
|
||||
geometry_id = self.geometry_cache["shapes"][element.id()]["geometry"]
|
||||
if geometry_id:
|
||||
mesh_name = tool.Loader.get_mesh_name(type("Geometry", (), {"id": geometry_id}))
|
||||
mesh = self.meshes.get(mesh_name)
|
||||
self.create_product(element, mesh=mesh)
|
||||
|
||||
def create_products(self, products, settings=None):
|
||||
if settings is None:
|
||||
settings = self.settings
|
||||
|
||||
results = set()
|
||||
if not products:
|
||||
return results
|
||||
if self.ifc_import_settings.should_use_cpu_multiprocessing:
|
||||
iterator = ifcopenshell.geom.iterator(
|
||||
self.settings, self.file, multiprocessing.cpu_count(), include=products
|
||||
)
|
||||
iterator = ifcopenshell.geom.iterator(settings, self.file, multiprocessing.cpu_count(), include=products)
|
||||
else:
|
||||
iterator = ifcopenshell.geom.iterator(self.settings, self.file, include=products)
|
||||
iterator = ifcopenshell.geom.iterator(settings, self.file, include=products)
|
||||
if self.ifc_import_settings.should_cache:
|
||||
cache = IfcStore.get_cache()
|
||||
if cache:
|
||||
@@ -783,10 +846,10 @@ class IfcImporter:
|
||||
self.structural_collection.children.link(self.structural_connection_collection)
|
||||
self.project["blender"].children.link(self.structural_collection)
|
||||
|
||||
self.create_curve_products(self.file.by_type("IfcStructuralCurveMember"))
|
||||
self.create_curve_products(self.file.by_type("IfcStructuralCurveConnection"))
|
||||
self.create_curve_products(self.file.by_type("IfcStructuralSurfaceMember"))
|
||||
self.create_curve_products(self.file.by_type("IfcStructuralSurfaceConnection"))
|
||||
self.create_products(self.file.by_type("IfcStructuralCurveMember"), settings=self.settings_2d)
|
||||
self.create_products(self.file.by_type("IfcStructuralCurveConnection"), settings=self.settings_2d)
|
||||
self.create_products(self.file.by_type("IfcStructuralSurfaceMember"), settings=self.settings_2d)
|
||||
self.create_products(self.file.by_type("IfcStructuralSurfaceConnection"), settings=self.settings_2d)
|
||||
self.create_structural_point_connections()
|
||||
|
||||
def create_structural_point_connections(self):
|
||||
@@ -874,40 +937,6 @@ class IfcImporter:
|
||||
self.link_element(product, obj)
|
||||
return product
|
||||
|
||||
def create_curve_products(self, products):
|
||||
results = set()
|
||||
if not products:
|
||||
return results
|
||||
if self.ifc_import_settings.should_use_cpu_multiprocessing:
|
||||
iterator = ifcopenshell.geom.iterator(
|
||||
self.settings_2d, self.file, multiprocessing.cpu_count(), include=products
|
||||
)
|
||||
else:
|
||||
iterator = ifcopenshell.geom.iterator(self.settings_2d, self.file, include=products)
|
||||
if self.ifc_import_settings.should_cache:
|
||||
cache = IfcStore.get_cache()
|
||||
if cache:
|
||||
iterator.set_cache(cache)
|
||||
valid_file = iterator.initialize()
|
||||
if not valid_file:
|
||||
return results
|
||||
checkpoint = time.time()
|
||||
total = 0
|
||||
while True:
|
||||
total += 1
|
||||
if total % 250 == 0:
|
||||
print("{} elements processed in {:.2f}s ...".format(total, time.time() - checkpoint))
|
||||
checkpoint = time.time()
|
||||
shape = iterator.get()
|
||||
if shape:
|
||||
product = self.file.by_id(shape.id)
|
||||
self.create_product(product, shape)
|
||||
results.add(product)
|
||||
if not iterator.next():
|
||||
break
|
||||
print("Done creating geometry")
|
||||
return results
|
||||
|
||||
def create_product(self, element, shape=None, mesh=None):
|
||||
if element is None:
|
||||
return
|
||||
@@ -921,23 +950,20 @@ class IfcImporter:
|
||||
|
||||
if mesh:
|
||||
pass
|
||||
elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
|
||||
mesh = self.create_camera(element, shape)
|
||||
self.link_mesh(shape, mesh)
|
||||
elif element.is_a("IfcAnnotation") and self.is_curve_annotation(element) and shape:
|
||||
mesh = self.create_curve(element, shape)
|
||||
self.link_mesh(shape, mesh)
|
||||
tool.Loader.link_mesh(shape, mesh)
|
||||
elif shape:
|
||||
mesh_name = self.get_mesh_name(shape.geometry)
|
||||
mesh_name = tool.Loader.get_mesh_name(shape.geometry)
|
||||
mesh = self.meshes.get(mesh_name)
|
||||
if mesh is None:
|
||||
mesh = self.create_mesh(element, shape)
|
||||
self.link_mesh(shape, mesh)
|
||||
tool.Loader.link_mesh(shape, mesh)
|
||||
self.meshes[mesh_name] = mesh
|
||||
else:
|
||||
mesh = None
|
||||
|
||||
obj = bpy.data.objects.new(self.get_name(element), mesh)
|
||||
obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh)
|
||||
self.link_element(element, obj)
|
||||
|
||||
if shape:
|
||||
@@ -990,9 +1016,37 @@ class IfcImporter:
|
||||
self.convert_representation(representation)
|
||||
|
||||
mesh = bpy.data.meshes.new("Native")
|
||||
|
||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||
mat = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
||||
if props.has_blender_offset and self.is_point_far_away(self.mesh_data["co"][0:3], is_meters=False):
|
||||
offset_point = np.linalg.inv(mat) @ np.array(
|
||||
(
|
||||
float(props.blender_eastings),
|
||||
float(props.blender_northings),
|
||||
float(props.blender_orthogonal_height),
|
||||
0.0,
|
||||
)
|
||||
)
|
||||
verts = [None] * len(self.mesh_data["co"])
|
||||
for i in range(0, len(self.mesh_data["co"]), 3):
|
||||
verts[i], verts[i + 1], verts[i + 2] = ifcopenshell.util.geolocation.enh2xyz(
|
||||
self.mesh_data["co"][i] * self.unit_scale,
|
||||
self.mesh_data["co"][i + 1] * self.unit_scale,
|
||||
self.mesh_data["co"][i + 2] * self.unit_scale,
|
||||
offset_point[0] * self.unit_scale,
|
||||
offset_point[1] * self.unit_scale,
|
||||
offset_point[2] * self.unit_scale,
|
||||
float(props.blender_x_axis_abscissa),
|
||||
float(props.blender_x_axis_ordinate),
|
||||
)
|
||||
mesh["has_cartesian_point_offset"] = True
|
||||
else:
|
||||
verts = [c * self.unit_scale for c in self.mesh_data["co"]]
|
||||
mesh["has_cartesian_point_offset"] = False
|
||||
|
||||
mesh.vertices.add(self.mesh_data["total_verts"])
|
||||
mesh.vertices.foreach_set("co", [c * self.unit_scale for c in self.mesh_data["co"]])
|
||||
# mesh.vertices.foreach_set("co", self.mesh_data["co"])
|
||||
mesh.vertices.foreach_set("co", verts)
|
||||
mesh.loops.add(len(self.mesh_data["vertex_index"]))
|
||||
mesh.loops.foreach_set("vertex_index", self.mesh_data["vertex_index"])
|
||||
mesh.polygons.add(self.mesh_data["total_polygons"])
|
||||
@@ -1285,7 +1339,6 @@ class IfcImporter:
|
||||
bpy.context.view_layer.objects.active = last_obj
|
||||
context_override = {}
|
||||
bpy.ops.object.editmode_toggle(context_override)
|
||||
bpy.ops.mesh.remove_doubles(context_override)
|
||||
bpy.ops.mesh.tris_convert_to_quads(context_override)
|
||||
bpy.ops.mesh.normals_make_consistent(context_override)
|
||||
bpy.ops.object.editmode_toggle(context_override)
|
||||
@@ -1320,43 +1373,54 @@ class IfcImporter:
|
||||
bpy.context.scene.unit_settings.length_unit = "FEET"
|
||||
elif unit.is_a("IfcNamedUnit") and unit.UnitType == "AREAUNIT":
|
||||
name = unit.Name if unit.is_a("IfcSIUnit") else unit.Name.lower()
|
||||
bpy.context.scene.BIMProperties.area_unit = "{}{}".format(
|
||||
unit.Prefix + "/" if hasattr(unit, "Prefix") and unit.Prefix else "", name
|
||||
)
|
||||
try:
|
||||
bpy.context.scene.BIMProperties.area_unit = "{}{}".format(
|
||||
unit.Prefix + "/" if hasattr(unit, "Prefix") and unit.Prefix else "", name
|
||||
)
|
||||
except: # Probably an invalid unit.
|
||||
bpy.context.scene.BIMProperties.area_unit = "SQUARE_METRE"
|
||||
elif unit.is_a("IfcNamedUnit") and unit.UnitType == "VOLUMEUNIT":
|
||||
name = unit.Name if unit.is_a("IfcSIUnit") else unit.Name.lower()
|
||||
bpy.context.scene.BIMProperties.volume_unit = "{}{}".format(
|
||||
unit.Prefix + "/" if hasattr(unit, "Prefix") and unit.Prefix else "", name
|
||||
)
|
||||
try:
|
||||
bpy.context.scene.BIMProperties.volume_unit = "{}{}".format(
|
||||
unit.Prefix + "/" if hasattr(unit, "Prefix") and unit.Prefix else "", name
|
||||
)
|
||||
except: # Probably an invalid unit.
|
||||
bpy.context.scene.BIMProperties.volume_unit = "CUBIC_METRE"
|
||||
|
||||
def create_project(self):
|
||||
project = self.file.by_type("IfcProject")[0]
|
||||
self.project = {"ifc": project}
|
||||
obj = tool.Ifc.get_object(project)
|
||||
if obj:
|
||||
self.project["blender"] = obj.users_collection[0]
|
||||
self.project["blender"] = obj.BIMObjectProperties.collection
|
||||
self.has_existing_project = True
|
||||
return
|
||||
self.project["blender"] = bpy.data.collections.new(
|
||||
"{}/{}".format(self.project["ifc"].is_a(), self.project["ifc"].Name)
|
||||
)
|
||||
obj = self.create_product(self.project["ifc"])
|
||||
if obj:
|
||||
self.project["blender"].objects.link(obj)
|
||||
self.project["blender"].objects.link(obj)
|
||||
self.project["blender"].BIMCollectionProperties.obj = obj
|
||||
obj.BIMObjectProperties.collection = self.project["blender"]
|
||||
|
||||
def create_collections(self):
|
||||
if self.ifc_import_settings.collection_mode == "DECOMPOSITION":
|
||||
self.create_decomposition_collections()
|
||||
elif self.ifc_import_settings.collection_mode == "SPATIAL_DECOMPOSITION":
|
||||
self.create_spatial_decomposition_collections()
|
||||
|
||||
def create_decomposition_collections(self):
|
||||
self.create_spatial_decomposition_collections()
|
||||
self.create_aggregate_collections()
|
||||
if self.ifc_import_settings.collection_mode == "DECOMPOSITION":
|
||||
self.create_aggregate_collections()
|
||||
elif self.ifc_import_settings.collection_mode == "SPATIAL_DECOMPOSITION":
|
||||
pass
|
||||
|
||||
def create_spatial_decomposition_collections(self):
|
||||
for rel_aggregate in self.project["ifc"].IsDecomposedBy or []:
|
||||
self.create_spatial_decomposition_collection(self.project["blender"], rel_aggregate.RelatedObjects)
|
||||
|
||||
# Invalid IFCs may have orphaned spatial structure elements.
|
||||
orphaned_spaces = [e for e in self.spatial_elements if e.GlobalId not in self.collections]
|
||||
while orphaned_spaces:
|
||||
self.create_spatial_decomposition_collection(self.project["blender"], orphaned_spaces)
|
||||
orphaned_spaces = [e for e in self.spatial_elements if e.GlobalId not in self.collections]
|
||||
|
||||
self.create_views_collection()
|
||||
self.create_type_collection()
|
||||
|
||||
@@ -1378,12 +1442,6 @@ class IfcImporter:
|
||||
if not view_collection:
|
||||
view_collection = bpy.data.collections.new("Views")
|
||||
self.project["blender"].children.link(view_collection)
|
||||
for element in self.file.by_type("IfcAnnotation"):
|
||||
if element.ObjectType == "DRAWING":
|
||||
group = [r for r in element.HasAssignments if r.is_a("IfcRelAssignsToGroup")][0].RelatingGroup
|
||||
collection = bpy.data.collections.new("IfcGroup/" + group.Name)
|
||||
self.collections[group.GlobalId] = collection
|
||||
view_collection.children.link(collection)
|
||||
|
||||
def create_spatial_decomposition_collection(self, parent, related_objects):
|
||||
for element in related_objects:
|
||||
@@ -1394,10 +1452,10 @@ class IfcImporter:
|
||||
obj = tool.Ifc.get_object(element)
|
||||
if obj:
|
||||
is_existing = True
|
||||
collection = obj.users_collection[0]
|
||||
collection = obj.BIMObjectProperties.collection
|
||||
self.collections[element.GlobalId] = collection
|
||||
if not is_existing:
|
||||
collection = bpy.data.collections.new(self.get_name(element))
|
||||
collection = bpy.data.collections.new(tool.Loader.get_name(element))
|
||||
self.collections[element.GlobalId] = collection
|
||||
parent.children.link(collection)
|
||||
if element.IsDecomposedBy:
|
||||
@@ -1410,7 +1468,11 @@ class IfcImporter:
|
||||
rel_aggregates += [e.Decomposes[0] for e in self.elements if e.Decomposes]
|
||||
rel_aggregates = set(rel_aggregates)
|
||||
else:
|
||||
rel_aggregates = [a for a in self.file.by_type("IfcRelAggregates") if a.RelatingObject.is_a("IfcElement")]
|
||||
rel_aggregates = [
|
||||
a
|
||||
for a in self.file.by_type("IfcRelAggregates")
|
||||
if a.RelatingObject.is_a("IfcElement") or a.RelatingObject.is_a("IfcElementType")
|
||||
]
|
||||
|
||||
if len(rel_aggregates) > 10000:
|
||||
# More than 10,000 collections makes Blender unhappy
|
||||
@@ -1421,7 +1483,7 @@ class IfcImporter:
|
||||
aggregates = {}
|
||||
for rel_aggregate in rel_aggregates:
|
||||
element = rel_aggregate.RelatingObject
|
||||
collection = bpy.data.collections.new(self.get_name(element))
|
||||
collection = bpy.data.collections.new(tool.Loader.get_name(element))
|
||||
aggregates[element.GlobalId] = {"element": element, "collection": collection}
|
||||
self.collections[element.GlobalId] = collection
|
||||
|
||||
@@ -1433,6 +1495,10 @@ class IfcImporter:
|
||||
parent = ifcopenshell.util.element.get_container(aggregate["element"])
|
||||
if parent:
|
||||
self.collections[parent.GlobalId].children.link(aggregate["collection"])
|
||||
continue
|
||||
if aggregate["element"].is_a("IfcElementType"):
|
||||
self.type_collection.children.link(aggregate["collection"])
|
||||
continue
|
||||
|
||||
def create_materials(self):
|
||||
for material in self.file.by_type("IfcMaterial"):
|
||||
@@ -1472,184 +1538,18 @@ class IfcImporter:
|
||||
if not blender_material:
|
||||
name = style.Name or str(style.id())
|
||||
blender_material = bpy.data.materials.new(name)
|
||||
blender_material.use_fake_user = True
|
||||
|
||||
self.link_element(style, blender_material)
|
||||
|
||||
blender_material.BIMMaterialProperties.ifc_style_id = style.id()
|
||||
self.material_creator.styles[style.id()] = blender_material
|
||||
|
||||
rendering_style = None
|
||||
texture_style = None
|
||||
|
||||
for surface_style in style.Styles:
|
||||
if surface_style.is_a() == "IfcSurfaceStyleShading":
|
||||
self.create_surface_style_shading(blender_material, surface_style)
|
||||
elif surface_style.is_a("IfcSurfaceStyleRendering"):
|
||||
rendering_style = surface_style
|
||||
self.create_surface_style_rendering(blender_material, surface_style)
|
||||
elif surface_style.is_a("IfcSurfaceStyleWithTextures"):
|
||||
texture_style = surface_style
|
||||
|
||||
if rendering_style and texture_style:
|
||||
self.create_surface_style_with_textures(blender_material, rendering_style, texture_style)
|
||||
|
||||
def create_surface_style_shading(self, blender_material, surface_style):
|
||||
alpha = 1.0
|
||||
# Transparency was added in IFC4
|
||||
if hasattr(surface_style, "Transparency") and surface_style.Transparency:
|
||||
alpha = 1 - surface_style.Transparency
|
||||
blender_material.diffuse_color = (
|
||||
surface_style.SurfaceColour.Red,
|
||||
surface_style.SurfaceColour.Green,
|
||||
surface_style.SurfaceColour.Blue,
|
||||
alpha,
|
||||
)
|
||||
|
||||
def create_surface_style_rendering(self, blender_material, surface_style):
|
||||
self.create_surface_style_shading(blender_material, surface_style)
|
||||
if surface_style.ReflectanceMethod in ["PHYSICAL", "NOTDEFINED"]:
|
||||
blender_material.use_nodes = True
|
||||
bsdf = blender_material.node_tree.nodes["Principled BSDF"]
|
||||
if surface_style.DiffuseColour:
|
||||
if surface_style.DiffuseColour.is_a("IfcColourRgb"):
|
||||
bsdf.inputs["Base Color"].default_value = (
|
||||
surface_style.DiffuseColour.Red,
|
||||
surface_style.DiffuseColour.Green,
|
||||
surface_style.DiffuseColour.Blue,
|
||||
1,
|
||||
)
|
||||
elif surface_style.DiffuseColour.is_a("IfcNormalisedRatioMeasure"):
|
||||
bsdf.inputs["Base Color"].default_value = (
|
||||
surface_style.SurfaceColour.Red * surface_style.DiffuseColour.wrappedValue,
|
||||
surface_style.SurfaceColour.Green * surface_style.DiffuseColour.wrappedValue,
|
||||
surface_style.SurfaceColour.Blue * surface_style.DiffuseColour.wrappedValue,
|
||||
1,
|
||||
)
|
||||
if surface_style.SpecularColour and surface_style.SpecularColour.is_a("IfcNormalisedRatioMeasure"):
|
||||
bsdf.inputs["Metallic"].default_value = surface_style.SpecularColour.wrappedValue
|
||||
if surface_style.SpecularHighlight and surface_style.SpecularHighlight.is_a("IfcSpecularRoughness"):
|
||||
bsdf.inputs["Roughness"].default_value = surface_style.SpecularHighlight.wrappedValue
|
||||
if hasattr(surface_style, "Transparency") and surface_style.Transparency:
|
||||
bsdf.inputs["Alpha"].default_value = 1 - surface_style.Transparency
|
||||
blender_material.blend_method = "BLEND"
|
||||
elif surface_style.ReflectanceMethod == "FLAT":
|
||||
blender_material.use_nodes = True
|
||||
|
||||
output = {n.type: n for n in blender_material.node_tree.nodes}.get("OUTPUT_MATERIAL", None)
|
||||
bsdf = blender_material.node_tree.nodes["Principled BSDF"]
|
||||
|
||||
mix = blender_material.node_tree.nodes.new(type="ShaderNodeMixShader")
|
||||
mix.location = bsdf.location
|
||||
blender_material.node_tree.links.new(mix.outputs[0], output.inputs["Surface"])
|
||||
|
||||
blender_material.node_tree.nodes.remove(bsdf)
|
||||
|
||||
lightpath = blender_material.node_tree.nodes.new(type="ShaderNodeLightPath")
|
||||
lightpath.location = mix.location - mathutils.Vector((200, -200))
|
||||
blender_material.node_tree.links.new(lightpath.outputs[0], mix.inputs[0])
|
||||
|
||||
bsdf = blender_material.node_tree.nodes.new(type="ShaderNodeBsdfTransparent")
|
||||
bsdf.location = mix.location - mathutils.Vector((200, 0))
|
||||
blender_material.node_tree.links.new(bsdf.outputs[0], mix.inputs[1])
|
||||
|
||||
rgb = blender_material.node_tree.nodes.new(type="ShaderNodeRGB")
|
||||
rgb.location = mix.location - mathutils.Vector((200, 200))
|
||||
blender_material.node_tree.links.new(rgb.outputs[0], mix.inputs[2])
|
||||
|
||||
if surface_style.DiffuseColour and surface_style.DiffuseColour.is_a("IfcColourRgb"):
|
||||
rgb.outputs[0].default_value = (
|
||||
surface_style.DiffuseColour.Red,
|
||||
surface_style.DiffuseColour.Green,
|
||||
surface_style.DiffuseColour.Blue,
|
||||
1,
|
||||
)
|
||||
|
||||
def create_surface_style_with_textures(self, blender_material, rendering_style, texture_style):
|
||||
for texture in texture_style.Textures:
|
||||
mode = getattr(texture, "Mode", None)
|
||||
node = None
|
||||
|
||||
if texture.is_a("IfcImageTexture"):
|
||||
image_url = texture.URLReference
|
||||
if not os.path.abspath(texture.URLReference) and tool.Ifc.get_path():
|
||||
image_url = os.path.join(os.path.dirname(tool.Ifc.get_path()), texture.URLReference)
|
||||
|
||||
if rendering_style.ReflectanceMethod in ["PHYSICAL", "NOTDEFINED"]:
|
||||
bsdf = blender_material.node_tree.nodes["Principled BSDF"]
|
||||
if mode == "NORMAL":
|
||||
normalmap = blender_material.node_tree.nodes.new(type="ShaderNodeNormalMap")
|
||||
normalmap.location = bsdf.location - mathutils.Vector((200, 0))
|
||||
blender_material.node_tree.links.new(normalmap.outputs[0], bsdf.inputs["Normal"])
|
||||
|
||||
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
node.location = normalmap.location - mathutils.Vector((200, 0))
|
||||
image = bpy.data.images.load(image_url)
|
||||
image.colorspace_settings.name = "Non-Color"
|
||||
node.image = image
|
||||
blender_material.node_tree.links.new(node.outputs[0], normalmap.inputs["Color"])
|
||||
elif mode == "EMISSIVE":
|
||||
output = {n.type: n for n in blender_material.node_tree.nodes}.get("OUTPUT_MATERIAL", None)
|
||||
|
||||
add = blender_material.node_tree.nodes.new(type="ShaderNodeAddShader")
|
||||
add.location = bsdf.location + mathutils.Vector((200, 0))
|
||||
blender_material.node_tree.links.new(bsdf.outputs[0], add.inputs[1])
|
||||
blender_material.node_tree.links.new(add.outputs[0], output.inputs[0])
|
||||
|
||||
emission = blender_material.node_tree.nodes.new(type="ShaderNodeEmission")
|
||||
emission.location = add.location - mathutils.Vector((200, 0))
|
||||
blender_material.node_tree.links.new(emission.outputs[0], add.inputs[0])
|
||||
|
||||
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
node.location = emission.location - mathutils.Vector((200, 0))
|
||||
image = bpy.data.images.load(image_url)
|
||||
node.image = image
|
||||
blender_material.node_tree.links.new(node.outputs[0], emission.inputs[0])
|
||||
elif mode == "METALLICROUGHNESS":
|
||||
separate = blender_material.node_tree.nodes.new(type="ShaderNodeSeparateRGB")
|
||||
separate.location = bsdf.location - mathutils.Vector((200, 0))
|
||||
blender_material.node_tree.links.new(separate.outputs[1], bsdf.inputs["Roughness"])
|
||||
blender_material.node_tree.links.new(separate.outputs[2], bsdf.inputs["Metallic"])
|
||||
|
||||
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
node.location = separate.location - mathutils.Vector((200, 0))
|
||||
image = bpy.data.images.load(image_url)
|
||||
image.colorspace_settings.name = "Non-Color"
|
||||
node.image = image
|
||||
blender_material.node_tree.links.new(node.outputs[0], separate.inputs[0])
|
||||
elif mode == "OCCLUSION":
|
||||
# TODO work out how to implement glTF settings here
|
||||
# https://docs.blender.org/manual/en/dev/addons/import_export/scene_gltf2.html
|
||||
pass
|
||||
elif mode == "DIFFUSE":
|
||||
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
node.location = bsdf.location - mathutils.Vector((400, 0))
|
||||
image = bpy.data.images.load(image_url)
|
||||
node.image = image
|
||||
blender_material.node_tree.links.new(node.outputs[0], bsdf.inputs["Base Color"])
|
||||
blender_material.node_tree.links.new(node.outputs[1], bsdf.inputs["Alpha"])
|
||||
blender_material.blend_method = "BLEND"
|
||||
elif rendering_style.ReflectanceMethod == "FLAT":
|
||||
bsdf = blender_material.node_tree.nodes["Mix Shader"]
|
||||
if mode == "EMISSIVE":
|
||||
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
node.location = bsdf.location - mathutils.Vector((200, 0))
|
||||
image = bpy.data.images.load(image_url)
|
||||
node.image = image
|
||||
blender_material.node_tree.links.new(node.outputs[0], bsdf.inputs[2])
|
||||
|
||||
if node and getattr(texture, "IsMappedBy", None):
|
||||
coordinates = texture.IsMappedBy[0]
|
||||
coord = blender_material.node_tree.nodes.new(type="ShaderNodeTexCoord")
|
||||
coord.location = node.location - mathutils.Vector((200, 0))
|
||||
if coordinates.is_a("IfcTextureCoordinateGenerator") and coordinates.Mode == "COORD":
|
||||
blender_material.node_tree.links.new(coord.outputs["Generated"], node.inputs["Vector"])
|
||||
elif coordinates.is_a("IfcTextureCoordinateGenerator") and coordinates.Mode == "COORD-EYE":
|
||||
blender_material.node_tree.links.new(coord.outputs["Camera"], node.inputs["Vector"])
|
||||
else:
|
||||
blender_material.node_tree.links.new(coord.outputs["UV"], node.inputs["Vector"])
|
||||
|
||||
def get_name(self, element):
|
||||
return "{}/{}".format(element.is_a(), element.Name)
|
||||
style_elements = tool.Style.get_style_elements(blender_material)
|
||||
if tool.Style.has_blender_external_style(style_elements):
|
||||
blender_material.BIMStyleProperties.active_style_type = "External"
|
||||
else:
|
||||
blender_material.BIMStyleProperties.active_style_type = "Shading"
|
||||
|
||||
def place_objects_in_collections(self):
|
||||
for ifc_definition_id, obj in self.added_data.items():
|
||||
@@ -1669,6 +1569,8 @@ class IfcImporter:
|
||||
return
|
||||
elif element.GlobalId in self.collections:
|
||||
collection = self.collections[element.GlobalId]
|
||||
collection.BIMCollectionProperties.obj = obj
|
||||
obj.BIMObjectProperties.collection = collection
|
||||
collection.name = obj.name
|
||||
return collection.objects.link(obj)
|
||||
elif getattr(element, "Decomposes", None):
|
||||
@@ -1683,7 +1585,10 @@ class IfcImporter:
|
||||
elif element.is_a("IfcGridAxis"):
|
||||
return
|
||||
elif element.GlobalId in self.collections:
|
||||
return self.collections[element.GlobalId].objects.link(obj)
|
||||
collection = self.collections[element.GlobalId]
|
||||
collection.BIMCollectionProperties.obj = obj
|
||||
obj.BIMObjectProperties.collection = collection
|
||||
return collection.objects.link(obj)
|
||||
elif element.is_a("IfcTypeObject"):
|
||||
return self.type_collection.objects.link(obj)
|
||||
elif element.is_a("IfcStructuralMember"):
|
||||
@@ -1710,22 +1615,19 @@ class IfcImporter:
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
|
||||
def is_curve_annotation(self, element):
|
||||
return element.ObjectType in [
|
||||
"DIMENSION",
|
||||
"EQUAL_DIMENSION",
|
||||
"PLAN_LEVEL",
|
||||
"SECTION_LEVEL",
|
||||
"STAIR_ARROW",
|
||||
"TEXT_LEADER",
|
||||
]
|
||||
object_type = element.ObjectType
|
||||
return object_type in ANNOTATION_TYPES_DATA and ANNOTATION_TYPES_DATA[object_type][3] == "curve"
|
||||
|
||||
def get_drawing_group(self, element):
|
||||
for rel in element.HasAssignments or []:
|
||||
if rel.is_a("IfcRelAssignsToGroup"):
|
||||
if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.ObjectType == "DRAWING":
|
||||
return rel.RelatingGroup
|
||||
|
||||
def get_element_matrix(self, element):
|
||||
result = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
||||
if isinstance(element, ifcopenshell.sqlite_entity):
|
||||
result = self.geometry_cache["shapes"][element.id()]["matrix"]
|
||||
else:
|
||||
result = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
||||
result[0][3] *= self.unit_scale
|
||||
result[1][3] *= self.unit_scale
|
||||
result[2][3] *= self.unit_scale
|
||||
@@ -1798,71 +1700,13 @@ class IfcImporter:
|
||||
):
|
||||
return representation.Items[0].MappingTarget
|
||||
|
||||
def get_mesh_name(self, geometry):
|
||||
representation_id = geometry.id
|
||||
if "-" in representation_id:
|
||||
representation_id = int(re.sub(r"\D", "", representation_id.split("-")[0]))
|
||||
else:
|
||||
representation_id = int(re.sub(r"\D", "", representation_id))
|
||||
representation = self.file.by_id(representation_id)
|
||||
context_id = representation.ContextOfItems.id() if hasattr(representation, "ContextOfItems") else 0
|
||||
return "{}/{}".format(context_id, representation_id)
|
||||
|
||||
def create_camera(self, element, shape):
|
||||
if hasattr(shape, "geometry"):
|
||||
geometry = shape.geometry
|
||||
else:
|
||||
geometry = shape
|
||||
|
||||
v = geometry.verts
|
||||
x = [v[i] for i in range(0, len(v), 3)]
|
||||
y = [v[i + 1] for i in range(0, len(v), 3)]
|
||||
z = [v[i + 2] for i in range(0, len(v), 3)]
|
||||
width = max(x) - min(x)
|
||||
height = max(y) - min(y)
|
||||
depth = max(z) - min(z)
|
||||
|
||||
camera = bpy.data.cameras.new(self.get_mesh_name(geometry))
|
||||
camera.type = "ORTHO"
|
||||
camera.ortho_scale = width if width > height else height
|
||||
camera.clip_end = depth
|
||||
|
||||
if width > height:
|
||||
camera.BIMCameraProperties.raster_x = 1000
|
||||
camera.BIMCameraProperties.raster_y = round(1000 * (height / width))
|
||||
else:
|
||||
camera.BIMCameraProperties.raster_x = round(1000 * (width / height))
|
||||
camera.BIMCameraProperties.raster_y = 1000
|
||||
|
||||
psets = ifcopenshell.util.element.get_psets(element)
|
||||
pset = psets.get("EPset_Drawing")
|
||||
if pset:
|
||||
if "TargetView" in pset:
|
||||
camera.BIMCameraProperties.target_view = pset["TargetView"]
|
||||
if "Scale" in pset:
|
||||
valid_scales = [
|
||||
i[0] for i in get_diagram_scales(None, bpy.context) if pset["Scale"] == i[0].split("|")[-1]
|
||||
]
|
||||
if valid_scales:
|
||||
camera.BIMCameraProperties.diagram_scale = valid_scales[0]
|
||||
else:
|
||||
camera.BIMCameraProperties.diagram_scale = "CUSTOM"
|
||||
camera.BIMCameraProperties.custom_diagram_scale = pset["Scale"]
|
||||
if "HasUnderlay" in pset:
|
||||
camera.BIMCameraProperties.has_underlay = pset["HasUnderlay"]
|
||||
if "HasLinework" in pset:
|
||||
camera.BIMCameraProperties.has_linework = pset["HasLinework"]
|
||||
if "HasAnnotation" in pset:
|
||||
camera.BIMCameraProperties.has_annotation = pset["HasAnnotation"]
|
||||
return camera
|
||||
|
||||
def create_curve(self, element, shape):
|
||||
if hasattr(shape, "geometry"):
|
||||
geometry = shape.geometry
|
||||
else:
|
||||
geometry = shape
|
||||
|
||||
curve = bpy.data.curves.new(self.get_mesh_name(geometry), type="CURVE")
|
||||
curve = bpy.data.curves.new(tool.Loader.get_mesh_name(geometry), type="CURVE")
|
||||
curve.dimensions = "3D"
|
||||
curve.resolution_u = 2
|
||||
|
||||
@@ -1888,7 +1732,7 @@ class IfcImporter:
|
||||
else:
|
||||
geometry = shape
|
||||
|
||||
mesh = bpy.data.meshes.new(self.get_mesh_name(geometry))
|
||||
mesh = bpy.data.meshes.new(tool.Loader.get_mesh_name(geometry))
|
||||
|
||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||
if (
|
||||
@@ -1940,6 +1784,7 @@ class IfcImporter:
|
||||
mesh.polygons.add(num_loops)
|
||||
mesh.polygons.foreach_set("loop_start", loop_start)
|
||||
mesh.polygons.foreach_set("loop_total", loop_total)
|
||||
mesh.polygons.foreach_set("use_smooth", [0] * total_faces)
|
||||
mesh.update()
|
||||
else:
|
||||
e = geometry.edges
|
||||
@@ -2003,17 +1848,6 @@ class IfcImporter:
|
||||
self.added_data[element.id()] = obj
|
||||
IfcStore.link_element(element, obj)
|
||||
|
||||
def link_mesh(self, shape, mesh):
|
||||
if hasattr(shape, "geometry"):
|
||||
geometry = shape.geometry
|
||||
else:
|
||||
geometry = shape
|
||||
if "-" in geometry.id:
|
||||
mesh.BIMMeshProperties.ifc_definition_id = int(geometry.id.split("-")[0])
|
||||
else:
|
||||
# TODO: See #2002
|
||||
mesh.BIMMeshProperties.ifc_definition_id = int(geometry.id.replace(",", ""))
|
||||
|
||||
def set_matrix_world(self, obj, matrix_world):
|
||||
obj.matrix_world = matrix_world
|
||||
tool.Geometry.record_object_position(obj)
|
||||
@@ -2027,6 +1861,7 @@ class IfcImportSettings:
|
||||
self.should_use_cpu_multiprocessing = True
|
||||
self.merge_mode = None
|
||||
self.should_merge_materials_by_colour = False
|
||||
self.should_load_geometry = True
|
||||
self.should_use_native_meshes = False
|
||||
self.should_clean_mesh = True
|
||||
self.should_cache = True
|
||||
@@ -2056,6 +1891,7 @@ class IfcImportSettings:
|
||||
settings.should_use_cpu_multiprocessing = props.should_use_cpu_multiprocessing
|
||||
settings.merge_mode = props.merge_mode
|
||||
settings.should_merge_materials_by_colour = props.should_merge_materials_by_colour
|
||||
settings.should_load_geometry = props.should_load_geometry
|
||||
settings.should_use_native_meshes = props.should_use_native_meshes
|
||||
settings.should_clean_mesh = props.should_clean_mesh
|
||||
settings.should_cache = props.should_cache
|
||||
|
||||
@@ -34,7 +34,6 @@ class AggregateData:
|
||||
cls.data = {
|
||||
"has_relating_object": cls.has_relating_object(),
|
||||
"relating_object_label": cls.get_relating_object_label(),
|
||||
"relating_object_id": cls.get_relating_object_id(),
|
||||
"has_related_objects": cls.has_related_objects(),
|
||||
"related_objects_amount": cls.get_related_objects_amount(),
|
||||
"ifc_class": cls.ifc_class(),
|
||||
@@ -55,12 +54,6 @@ class AggregateData:
|
||||
if aggregate:
|
||||
return f"{aggregate.is_a()}/{aggregate.Name or ''}"
|
||||
|
||||
@classmethod
|
||||
def get_relating_object_id(cls) -> int:
|
||||
aggregate = cls.get_relating_object()
|
||||
if aggregate:
|
||||
return aggregate.id()
|
||||
|
||||
@classmethod
|
||||
def get_related_objects(cls):
|
||||
return ifcopenshell.util.element.get_parts(tool.Ifc.get_entity(bpy.context.active_object))
|
||||
|
||||
@@ -40,16 +40,31 @@ class BIM_OT_assign_object(bpy.types.Operator, Operator):
|
||||
bl_label = "Assign Object"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
relating_object: bpy.props.IntProperty()
|
||||
related_object: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
core.assign_object(
|
||||
tool.Ifc,
|
||||
tool.Aggregate,
|
||||
tool.Collector,
|
||||
relating_obj=tool.Ifc.get_object(tool.Ifc.get().by_id(self.relating_object)),
|
||||
related_obj=tool.Ifc.get_object(tool.Ifc.get().by_id(self.related_object)),
|
||||
)
|
||||
relating_obj = None
|
||||
if self.relating_object:
|
||||
relating_obj = tool.Ifc.get_object(tool.Ifc.get().by_id(self.relating_object))
|
||||
elif context.active_object:
|
||||
relating_obj = context.active_object
|
||||
if not relating_obj:
|
||||
return
|
||||
|
||||
for obj in bpy.context.selected_objects:
|
||||
if obj == relating_obj:
|
||||
continue
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
continue
|
||||
result = core.assign_object(
|
||||
tool.Ifc,
|
||||
tool.Aggregate,
|
||||
tool.Collector,
|
||||
relating_obj=relating_obj,
|
||||
related_obj=obj,
|
||||
)
|
||||
if not result:
|
||||
self.report({"ERROR"}, f" Cannot aggregate {obj.name} to {relating_obj.name}")
|
||||
|
||||
|
||||
class BIM_OT_unassign_object(bpy.types.Operator, Operator):
|
||||
@@ -58,16 +73,22 @@ class BIM_OT_unassign_object(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.unassign_object"
|
||||
bl_label = "Unassign Object"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
relating_object: bpy.props.IntProperty()
|
||||
related_object: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
core.unassign_object(
|
||||
tool.Ifc,
|
||||
tool.Collector,
|
||||
relating_obj=tool.Ifc.get_object(tool.Ifc.get().by_id(self.relating_object)),
|
||||
related_obj=tool.Ifc.get_object(tool.Ifc.get().by_id(self.related_object)),
|
||||
)
|
||||
for obj in bpy.context.selected_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
continue
|
||||
aggregate = ifcopenshell.util.element.get_aggregate(element)
|
||||
if not aggregate:
|
||||
continue
|
||||
core.unassign_object(
|
||||
tool.Ifc,
|
||||
tool.Aggregate,
|
||||
tool.Collector,
|
||||
relating_obj=tool.Ifc.get_object(aggregate),
|
||||
related_obj=tool.Ifc.get_object(element),
|
||||
)
|
||||
|
||||
|
||||
class BIM_OT_enable_editing_aggregate(bpy.types.Operator, Operator):
|
||||
@@ -92,52 +113,58 @@ class BIM_OT_disable_editing_aggregate(bpy.types.Operator, Operator):
|
||||
core.disable_editing_aggregate(tool.Aggregate, obj=context.active_object)
|
||||
|
||||
|
||||
class BIM_OT_add_aggregate(bpy.types.Operator):
|
||||
class BIM_OT_add_aggregate(bpy.types.Operator, tool.Ifc.Operator):
|
||||
"""Add aggregate to IFC element"""
|
||||
|
||||
bl_idname = "bim.add_aggregate"
|
||||
bl_label = "Add Aggregate"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
obj: bpy.props.StringProperty()
|
||||
ifc_class: bpy.props.StringProperty(name="IFC Class", default="IfcElementAssembly")
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def draw(self, context):
|
||||
row = self.layout
|
||||
row.prop(self, "ifc_class")
|
||||
|
||||
def _execute(self, context):
|
||||
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
return {"FINISHED"}
|
||||
try:
|
||||
ifc_class = tool.Ifc.schema().declaration_by_name(self.ifc_class).name()
|
||||
except:
|
||||
return
|
||||
aggregate = self.create_aggregate(context, ifc_class)
|
||||
|
||||
aggregate = self.create_aggregate(context)
|
||||
tool.Collector.sync(obj)
|
||||
current_aggregate = ifcopenshell.util.element.get_aggregate(element)
|
||||
current_container = ifcopenshell.util.element.get_container(element)
|
||||
if current_aggregate:
|
||||
core.assign_object(
|
||||
tool.Ifc,
|
||||
tool.Aggregate,
|
||||
tool.Collector,
|
||||
relating_obj=tool.Ifc.get_object(current_aggregate),
|
||||
related_obj=aggregate,
|
||||
)
|
||||
elif current_container:
|
||||
blenderbim.core.spatial.assign_container(
|
||||
tool.Ifc,
|
||||
tool.Collector,
|
||||
tool.Spatial,
|
||||
structure_obj=tool.Ifc.get_object(current_container),
|
||||
element_obj=aggregate,
|
||||
)
|
||||
core.assign_object(tool.Ifc, tool.Aggregate, tool.Collector, relating_obj=aggregate, related_obj=obj)
|
||||
return {"FINISHED"}
|
||||
for obj in context.selected_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
continue
|
||||
|
||||
def create_aggregate(self, context):
|
||||
aggregate_collection = bpy.data.collections.new("IfcElementAssembly/Assembly")
|
||||
context.scene.collection.children.link(aggregate_collection)
|
||||
tool.Collector.sync(obj)
|
||||
current_aggregate = ifcopenshell.util.element.get_aggregate(element)
|
||||
current_container = ifcopenshell.util.element.get_container(element)
|
||||
if current_aggregate:
|
||||
core.assign_object(
|
||||
tool.Ifc,
|
||||
tool.Aggregate,
|
||||
tool.Collector,
|
||||
relating_obj=tool.Ifc.get_object(current_aggregate),
|
||||
related_obj=aggregate,
|
||||
)
|
||||
elif current_container:
|
||||
blenderbim.core.spatial.assign_container(
|
||||
tool.Ifc,
|
||||
tool.Collector,
|
||||
tool.Spatial,
|
||||
structure_obj=tool.Ifc.get_object(current_container),
|
||||
element_obj=aggregate,
|
||||
)
|
||||
core.assign_object(tool.Ifc, tool.Aggregate, tool.Collector, relating_obj=aggregate, related_obj=obj)
|
||||
|
||||
def create_aggregate(self, context, ifc_class):
|
||||
aggregate = bpy.data.objects.new("Assembly", None)
|
||||
aggregate_collection.objects.link(aggregate)
|
||||
bpy.ops.bim.assign_class(obj=aggregate.name, ifc_class="IfcElementAssembly")
|
||||
bpy.ops.bim.assign_class(obj=aggregate.name, ifc_class=ifc_class)
|
||||
return aggregate
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ class BIM_PT_aggregate(Panel):
|
||||
if props.relating_object:
|
||||
op = row.operator("bim.assign_object", icon="CHECKMARK", text="")
|
||||
op.relating_object = props.relating_object.BIMObjectProperties.ifc_definition_id
|
||||
op.related_object = context.active_object.BIMObjectProperties.ifc_definition_id
|
||||
row.operator("bim.disable_editing_aggregate", icon="CANCEL", text="")
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
@@ -67,8 +66,6 @@ class BIM_PT_aggregate(Panel):
|
||||
row.operator("bim.enable_editing_aggregate", icon="GREASEPENCIL", text="")
|
||||
row.operator("bim.add_aggregate", icon="ADD", text="")
|
||||
op = row.operator("bim.unassign_object", icon="X", text="")
|
||||
op.relating_object = AggregateData.data["relating_object_id"]
|
||||
op.related_object = context.active_object.BIMObjectProperties.ifc_definition_id
|
||||
else:
|
||||
row.label(text="No Aggregate", icon="TRIA_UP")
|
||||
row.operator("bim.enable_editing_aggregate", icon="GREASEPENCIL", text="")
|
||||
|
||||
@@ -59,9 +59,13 @@ class MaterialAttributesData:
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.data = {"attributes": cls.attributes()}
|
||||
cls.data = {"ifc_definition_id": cls.ifc_definition_id(), "attributes": cls.attributes()}
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def ifc_definition_id(cls):
|
||||
return bpy.context.active_object.active_material.BIMObjectProperties.ifc_definition_id
|
||||
|
||||
@classmethod
|
||||
def attributes(cls):
|
||||
results = []
|
||||
|
||||
@@ -25,7 +25,6 @@ import blenderbim.bim.handler
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.core.attribute as core
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.attribute.data import Data
|
||||
|
||||
|
||||
class Operator:
|
||||
@@ -51,9 +50,22 @@ class EnableEditingAttributes(bpy.types.Operator):
|
||||
oprops = obj.BIMObjectProperties
|
||||
props = obj.BIMAttributeProperties
|
||||
props.attributes.clear()
|
||||
if oprops.ifc_definition_id not in Data.products:
|
||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||
blenderbim.bim.helper.import_attributes2(tool.Ifc.get().by_id(oprops.ifc_definition_id), props.attributes)
|
||||
|
||||
def callback(name, prop, data):
|
||||
if name in ("RefLatitude", "RefLongitude"):
|
||||
new = props.attributes.add()
|
||||
new.name = name
|
||||
new.is_null = data[name] is None
|
||||
new.is_optional = True
|
||||
new.data_type = "string"
|
||||
new.ifc_class = data["type"]
|
||||
new.string_value = "" if new.is_null else json.dumps(data[name])
|
||||
blenderbim.bim.helper.add_attribute_description(new)
|
||||
new.description += " The degrees, minutes and seconds should follow this format : [12,34,56]"
|
||||
|
||||
blenderbim.bim.helper.import_attributes2(
|
||||
tool.Ifc.get().by_id(oprops.ifc_definition_id), props.attributes, callback=callback
|
||||
)
|
||||
props.is_editing_attributes = True
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -88,33 +100,22 @@ class EditAttributes(bpy.types.Operator, Operator):
|
||||
obj = bpy.data.objects.get(self.obj)
|
||||
elif self.obj_type == "Material":
|
||||
obj = bpy.data.materials.get(self.obj)
|
||||
oprops = obj.BIMObjectProperties
|
||||
props = obj.BIMAttributeProperties
|
||||
attributes = {}
|
||||
for attribute in Data.products[oprops.ifc_definition_id]:
|
||||
blender_attribute = props.attributes.get(attribute["name"])
|
||||
if not blender_attribute:
|
||||
continue
|
||||
if attribute["is_optional"] and blender_attribute.is_null:
|
||||
attributes[attribute["name"]] = None
|
||||
elif attribute["type"] == "string":
|
||||
attributes[attribute["name"]] = blender_attribute.string_value
|
||||
elif attribute["type"] == "list":
|
||||
values = blender_attribute.string_value[1:-1].split(", ")
|
||||
if attribute["list_type"] == "float":
|
||||
values = [float(v) for v in values]
|
||||
elif attribute["list_type"] == "integer":
|
||||
values = [int(v) for v in values]
|
||||
attributes[attribute["name"]] = values
|
||||
elif attribute["type"] == "integer":
|
||||
attributes[attribute["name"]] = blender_attribute.int_value
|
||||
elif attribute["type"] == "float":
|
||||
attributes[attribute["name"]] = blender_attribute.float_value
|
||||
elif attribute["type"] == "enum":
|
||||
attributes[attribute["name"]] = blender_attribute.enum_value
|
||||
product = self.file.by_id(oprops.ifc_definition_id)
|
||||
ifcopenshell.api.run("attribute.edit_attributes", self.file, **{"product": product, "attributes": attributes})
|
||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||
product = tool.Ifc.get_entity(obj)
|
||||
|
||||
def callback(attributes, prop):
|
||||
if prop.name in ("RefLatitude", "RefLongitude"):
|
||||
if prop.is_null:
|
||||
attributes[prop.name] = None
|
||||
else:
|
||||
try:
|
||||
attributes[prop.name] = json.loads(prop.string_value)
|
||||
except:
|
||||
attributes[prop.name] = None
|
||||
return True
|
||||
|
||||
attributes = blenderbim.bim.helper.export_attributes(props.attributes, callback=callback)
|
||||
ifcopenshell.api.run("attribute.edit_attributes", self.file, product=product, attributes=attributes)
|
||||
bpy.ops.bim.disable_editing_attributes(obj=obj.name, obj_type=self.obj_type)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -143,5 +144,5 @@ class CopyAttributeToSelection(bpy.types.Operator, Operator):
|
||||
|
||||
def _execute(self, context):
|
||||
value = context.active_object.BIMAttributeProperties.attributes.get(self.name).get_value()
|
||||
for obj in context.selected_objects:
|
||||
for obj in tool.Blender.get_selected_objects():
|
||||
core.copy_attribute_to_selection(tool.Ifc, name=self.name, value=value, obj=obj)
|
||||
|
||||
@@ -94,4 +94,10 @@ class BIM_PT_material_attributes(Panel):
|
||||
def draw(self, context):
|
||||
if not MaterialAttributesData.is_loaded:
|
||||
MaterialAttributesData.load()
|
||||
elif (
|
||||
context.active_object.active_material.BIMObjectProperties.ifc_definition_id
|
||||
!= MaterialAttributesData.data["ifc_definition_id"]
|
||||
):
|
||||
MaterialAttributesData.load()
|
||||
|
||||
draw_ui(context, self.layout, "Material", MaterialAttributesData.data["attributes"])
|
||||
|
||||
@@ -20,43 +20,45 @@ import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
classes = (
|
||||
operator.NewBcfProject,
|
||||
operator.LoadBcfProject,
|
||||
operator.LoadBcfTopics,
|
||||
operator.LoadBcfTopic,
|
||||
operator.LoadBcfComments,
|
||||
operator.EditBcfProjectName,
|
||||
operator.EditBcfAuthor,
|
||||
operator.EditBcfTopicName,
|
||||
operator.EditBcfTopic,
|
||||
operator.SaveBcfProject,
|
||||
operator.AddBcfTopic,
|
||||
operator.AddBcfHeaderFile,
|
||||
operator.AddBcfBimSnippet,
|
||||
operator.AddBcfReferenceLink,
|
||||
operator.AddBcfDocumentReference,
|
||||
operator.AddBcfLabel,
|
||||
operator.AddBcfRelatedTopic,
|
||||
operator.ViewBcfTopic,
|
||||
operator.RemoveBcfTopic,
|
||||
operator.RemoveBcfComment,
|
||||
operator.RemoveBcfBimSnippet,
|
||||
operator.RemoveBcfReferenceLink,
|
||||
operator.RemoveBcfDocumentReference,
|
||||
operator.RemoveBcfRelatedTopic,
|
||||
operator.EditBcfReferenceLinks,
|
||||
operator.EditBcfLabels,
|
||||
operator.RemoveBcfLabel,
|
||||
operator.EditBcfComment,
|
||||
operator.AddBcfComment,
|
||||
operator.ActivateBcfViewpoint,
|
||||
operator.AddBcfBimSnippet,
|
||||
operator.AddBcfComment,
|
||||
operator.AddBcfDocumentReference,
|
||||
operator.AddBcfHeaderFile,
|
||||
operator.AddBcfLabel,
|
||||
operator.AddBcfReferenceLink,
|
||||
operator.AddBcfRelatedTopic,
|
||||
operator.AddBcfTopic,
|
||||
operator.AddBcfViewpoint,
|
||||
operator.RemoveBcfViewpoint,
|
||||
operator.RemoveBcfFile,
|
||||
operator.EditBcfAuthor,
|
||||
operator.EditBcfComment,
|
||||
operator.EditBcfLabels,
|
||||
operator.EditBcfProjectName,
|
||||
operator.EditBcfReferenceLinks,
|
||||
operator.EditBcfTopic,
|
||||
operator.EditBcfTopicName,
|
||||
operator.ExtractBcfFile,
|
||||
operator.LoadBcfComments,
|
||||
operator.LoadBcfProject,
|
||||
operator.LoadBcfTopic,
|
||||
operator.LoadBcfTopics,
|
||||
operator.NewBcfProject,
|
||||
operator.OpenBcfReferenceLink,
|
||||
operator.SelectBcfHeaderFile,
|
||||
operator.RemoveBcfBimSnippet,
|
||||
operator.RemoveBcfComment,
|
||||
operator.RemoveBcfDocumentReference,
|
||||
operator.RemoveBcfFile,
|
||||
operator.RemoveBcfLabel,
|
||||
operator.RemoveBcfReferenceLink,
|
||||
operator.RemoveBcfRelatedTopic,
|
||||
operator.RemoveBcfTopic,
|
||||
operator.RemoveBcfViewpoint,
|
||||
operator.SaveBcfProject,
|
||||
operator.SelectBcfBimSnippetReference,
|
||||
operator.SelectBcfDocumentReference,
|
||||
operator.SelectBcfHeaderFile,
|
||||
operator.UnloadBcfProject,
|
||||
operator.ViewBcfTopic,
|
||||
prop.BcfReferenceLink,
|
||||
prop.BcfLabel,
|
||||
prop.BcfBimSnippet,
|
||||
|
||||
@@ -20,14 +20,20 @@ import os
|
||||
import bpy
|
||||
import bcf
|
||||
import bcf.bcfxml
|
||||
import bcf.v2.model
|
||||
import uuid
|
||||
import numpy as np
|
||||
import tempfile
|
||||
import webbrowser
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.unit
|
||||
from . import bcfstore
|
||||
import blenderbim.bim.module.bcf.prop as bcf_prop
|
||||
from . import bcfstore
|
||||
from pathlib import Path
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from math import radians, degrees, atan, tan, cos, sin
|
||||
from mathutils import Vector, Matrix, Euler, geometry
|
||||
from xsdata.models.datatype import XmlDateTime
|
||||
|
||||
|
||||
class NewBcfProject(bpy.types.Operator):
|
||||
@@ -52,11 +58,9 @@ class LoadBcfProject(bpy.types.Operator):
|
||||
filter_glob: bpy.props.StringProperty(default="*.bcf;*.bcfzip", options={"HIDDEN"})
|
||||
|
||||
def execute(self, context):
|
||||
context.scene.BCFProperties.is_loaded = False
|
||||
if self.filepath:
|
||||
bcfstore.BcfStore.bcfxml = bcf.bcfxml.load(self.filepath)
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
bcfxml.get_project()
|
||||
context.scene.BCFProperties.name = bcfxml.project.name
|
||||
bpy.ops.bim.load_bcf_topics()
|
||||
context.scene.BCFProperties.is_loaded = True
|
||||
@@ -67,6 +71,17 @@ class LoadBcfProject(bpy.types.Operator):
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
|
||||
class UnloadBcfProject(bpy.types.Operator):
|
||||
bl_idname = "bim.unload_bcf_project"
|
||||
bl_label = "Unload BCF Project"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
bcfstore.BcfStore.set(None)
|
||||
context.scene.BCFProperties.is_loaded = False
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class LoadBcfTopics(bpy.types.Operator):
|
||||
bl_idname = "bim.load_bcf_topics"
|
||||
bl_label = "Load BCF Topics"
|
||||
@@ -74,7 +89,6 @@ class LoadBcfTopics(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
bcfxml.get_topics()
|
||||
context.scene.BCFProperties.topics.clear()
|
||||
for index, topic_guid in enumerate(bcfxml.topics.keys()):
|
||||
new = context.scene.BCFProperties.topics.add()
|
||||
@@ -91,7 +105,7 @@ class LoadBcfTopic(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
topic = bcfxml.get_topic(self.topic_guid)
|
||||
topic = bcfxml.topics[self.topic_guid]
|
||||
bcfxml.get_header(self.topic_guid)
|
||||
new = context.scene.BCFProperties.topics[self.topic_index]
|
||||
data_map = {
|
||||
@@ -125,10 +139,10 @@ class LoadBcfTopic(bpy.types.Operator):
|
||||
|
||||
if topic.topic.bim_snippet:
|
||||
data_map = {
|
||||
"type": topic.bim_snippet.snippet_type,
|
||||
"is_external": topic.bim_snippet.is_external,
|
||||
"reference": topic.bim_snippet.reference,
|
||||
"schema": topic.bim_snippet.reference_schema,
|
||||
"type": topic.topic.bim_snippet.snippet_type,
|
||||
"is_external": topic.topic.bim_snippet.is_external,
|
||||
"reference": topic.topic.bim_snippet.reference,
|
||||
"schema": topic.topic.bim_snippet.reference_schema,
|
||||
}
|
||||
for key, value in data_map.items():
|
||||
if value is not None:
|
||||
@@ -164,10 +178,9 @@ class LoadBcfComments(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
bcfxml.get_comments(self.topic_guid)
|
||||
blender_topic = context.scene.BCFProperties.topics.get(self.topic_guid)
|
||||
blender_topic.comments.clear()
|
||||
for comment in bcfxml.topics[self.topic_guid].comments.values():
|
||||
for comment in bcfxml.topics[self.topic_guid].comments:
|
||||
new = blender_topic.comments.add()
|
||||
data_map = {
|
||||
"name": comment.guid,
|
||||
@@ -192,7 +205,6 @@ class EditBcfProjectName(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
bcfxml.project.name = context.scene.BCFProperties.name
|
||||
bcfxml.edit_project()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -216,9 +228,8 @@ class EditBcfTopicName(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
topic = bcfxml.topics[blender_topic.name].topic
|
||||
topic.title = blender_topic.title
|
||||
bcfxml.edit_topic(topic)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -232,7 +243,7 @@ class EditBcfTopic(bpy.types.Operator):
|
||||
blender_topic = props.active_topic
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
topic = bcfxml.topics[blender_topic.name].topic
|
||||
topic.title = blender_topic.title or None
|
||||
topic.priority = blender_topic.priority or None
|
||||
topic.due_date = blender_topic.due_date or None
|
||||
@@ -242,7 +253,6 @@ class EditBcfTopic(bpy.types.Operator):
|
||||
topic.topic_status = blender_topic.status or None
|
||||
topic.topic_type = blender_topic.type or None
|
||||
|
||||
bcfxml.edit_topic(topic)
|
||||
props.refresh_topic(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -256,7 +266,7 @@ class SaveBcfProject(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
bcfxml.save_project(self.filepath)
|
||||
bcfxml.save(self.filepath)
|
||||
return {"FINISHED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
@@ -299,15 +309,17 @@ class AddBcfBimSnippet(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
bim_snippet = bcf.v2.data.BimSnippet()
|
||||
bim_snippet.reference = props.bim_snippet_reference
|
||||
bim_snippet.reference_schema = props.bim_snippet_schema
|
||||
bim_snippet.snippet_type = props.bim_snippet_type
|
||||
bcfxml.add_bim_snippet(topic, bim_snippet)
|
||||
is_external = "://" in props.bim_snippet_reference
|
||||
bim_snippet = bcf.v2.model.BimSnippet(
|
||||
reference=props.bim_snippet_reference if is_external else Path(props.bim_snippet_reference).name,
|
||||
reference_schema=props.bim_snippet_schema,
|
||||
snippet_type=props.bim_snippet_type,
|
||||
is_external=is_external,
|
||||
)
|
||||
topic.topic.bim_snippet = bim_snippet
|
||||
with open(props.bim_snippet_reference, "r") as f:
|
||||
topic.bim_snippet = f.read()
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
bim_snippet.reference = ""
|
||||
bim_snippet.reference_schema = ""
|
||||
bim_snippet.snippet_type = ""
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -326,15 +338,14 @@ class AddBcfRelatedTopic(bpy.types.Operator):
|
||||
if props.related_topic == blender_topic.title:
|
||||
# Prevent adding self as related topic
|
||||
return False
|
||||
related_topic = None
|
||||
related_topic_guid = None
|
||||
for topic in bcfxml.topics.values():
|
||||
if topic.title == props.related_topic:
|
||||
related_topic = bcf.v2.data.RelatedTopic()
|
||||
related_topic.guid = topic.guid
|
||||
if topic.topic.title == props.related_topic:
|
||||
related_topic_guid = topic.guid
|
||||
break
|
||||
if not related_topic:
|
||||
if not related_topic_guid:
|
||||
return False
|
||||
if str(related_topic.guid) in [t.name for t in blender_topic.related_topics]:
|
||||
if str(related_topic_guid) in [t.name for t in blender_topic.related_topics]:
|
||||
# Prevent adding the same related topic more than once
|
||||
return False
|
||||
return True
|
||||
@@ -343,11 +354,12 @@ class AddBcfRelatedTopic(bpy.types.Operator):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
related_topic = bcf.v2.data.RelatedTopic()
|
||||
related_topic.guid = next((t for t in bcfxml.topics.values() if t.title == props.related_topic)).guid
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
topic.related_topics.append(related_topic)
|
||||
bcfxml.edit_topic(topic)
|
||||
topic.topic.related_topic.append(
|
||||
bcf.v2.model.TopicRelatedTopic(
|
||||
guid=next((t for t in bcfxml.topics.values() if t.topic.title == props.related_topic)).guid
|
||||
)
|
||||
)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
props.related_topic = ""
|
||||
return {"FINISHED"}
|
||||
@@ -367,15 +379,24 @@ class AddBcfHeaderFile(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
header_file = bcf.v2.data.HeaderFile()
|
||||
header_file.reference = props.file_reference
|
||||
if not os.path.exists(header_file.reference):
|
||||
header_file.filename = header_file.reference
|
||||
if len(props.file_ifc_project) == 22:
|
||||
header_file.ifc_project = props.file_ifc_project
|
||||
if len(props.file_ifc_spatial_structure_element) == 22:
|
||||
header_file.ifc_spatial_structure_element = props.file_ifc_spatial_structure_element
|
||||
bcfxml.add_file(topic, header_file)
|
||||
|
||||
is_external = "://" in props.file_reference
|
||||
filename = Path(props.file_reference).name if os.path.exists(props.file_reference) else None
|
||||
|
||||
if filename:
|
||||
with open(props.file_reference, "r") as f:
|
||||
topic.reference_files[filename] = f.read()
|
||||
|
||||
header_file = bcf.v2.model.HeaderFile(
|
||||
filename=filename,
|
||||
date=XmlDateTime.now(),
|
||||
reference=props.file_reference if is_external else Path(props.file_reference).name,
|
||||
ifc_project=props.file_ifc_project,
|
||||
ifc_spatial_structure_element=props.file_ifc_spatial_structure_element,
|
||||
is_external=is_external,
|
||||
)
|
||||
topic.header.file.append(header_file)
|
||||
|
||||
props.refresh_topic(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -409,27 +430,34 @@ class AddBcfViewpoint(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
viewpoint = bcf.v2.data.Viewpoint()
|
||||
|
||||
if blender_camera.data.type == "ORTHO":
|
||||
camera = bcf.v2.data.OrthogonalCamera()
|
||||
camera.view_to_world_scale = blender_camera.data.ortho_scale
|
||||
viewpoint.orthogonal_camera = camera
|
||||
elif blender_camera.data.type == "PERSP":
|
||||
camera = bcf.v2.data.PerspectiveCamera()
|
||||
camera.field_of_view = degrees(blender_camera.data.angle)
|
||||
viewpoint.perspective_camera = camera
|
||||
camera.camera_view_point.x = blender_camera.location.x
|
||||
camera.camera_view_point.y = blender_camera.location.y
|
||||
camera.camera_view_point.z = blender_camera.location.z
|
||||
direction = blender_camera.matrix_world.to_quaternion() @ Vector((0.0, 0.0, -1.0))
|
||||
camera.camera_direction.x = direction.x
|
||||
camera.camera_direction.y = direction.y
|
||||
camera.camera_direction.z = direction.z
|
||||
up = blender_camera.matrix_world.to_quaternion() @ Vector((0.0, 1.0, 0.0))
|
||||
camera.camera_up_vector.x = up.x
|
||||
camera.camera_up_vector.y = up.y
|
||||
camera.camera_up_vector.z = up.z
|
||||
|
||||
camera_view_point = bcf.v2.model.Point(
|
||||
x=blender_camera.location.x, y=blender_camera.location.y, z=blender_camera.location.z
|
||||
)
|
||||
camera_direction = bcf.v2.model.Direction(x=direction.x, y=direction.y, z=direction.z)
|
||||
camera_up_vector = bcf.v2.model.Direction(x=up.x, y=up.y, z=up.z)
|
||||
if blender_camera.data.type == "ORTHO":
|
||||
camera = bcf.v2.model.OrthogonalCamera(
|
||||
view_to_world_scale=blender_camera.data.ortho_scale,
|
||||
camera_view_point=camera_view_point,
|
||||
camera_direction=camera_direction,
|
||||
camera_up_vector=camera_up_vector,
|
||||
)
|
||||
visualization_info = bcf.v2.model.VisualizationInfo(orthogonal_camera=camera)
|
||||
elif blender_camera.data.type == "PERSP":
|
||||
camera = bcf.v2.model.PerspectiveCamera(
|
||||
field_of_view=degrees(blender_camera.data.angle),
|
||||
camera_view_point=camera_view_point,
|
||||
camera_direction=camera_direction,
|
||||
camera_up_vector=camera_up_vector,
|
||||
)
|
||||
visualization_info = bcf.v2.model.VisualizationInfo(guid=str(uuid.uuid4()), perspective_camera=camera)
|
||||
|
||||
# TODO allow the user to enable or disable snapshotting
|
||||
snapshot = None
|
||||
|
||||
blender_render = context.scene.render
|
||||
old_file_format = blender_render.image_settings.file_format
|
||||
@@ -437,9 +465,17 @@ class AddBcfViewpoint(bpy.types.Operator):
|
||||
old_filepath = blender_render.filepath
|
||||
blender_render.filepath = os.path.join(context.scene.BIMProperties.data_dir, "snapshot.png")
|
||||
bpy.ops.render.opengl(write_still=True)
|
||||
viewpoint.snapshot = blender_render.filepath
|
||||
with open(blender_render.filepath, "rb") as f:
|
||||
snapshot = f.read()
|
||||
# viewpoint.snapshot = blender_render.filepath
|
||||
|
||||
# TODO we should handle selection and visibility state
|
||||
vizinfo = bcf.v2.visinfo.VisualizationInfoHandler(visualization_info=visualization_info, snapshot=snapshot)
|
||||
topic.viewpoints[vizinfo.guid + ".bcfv"] = vizinfo
|
||||
topic.markup.viewpoints.append(
|
||||
bcf.v2.model.ViewPoint(viewpoint=vizinfo.guid + ".bcfv", guid=vizinfo.guid, snapshot=vizinfo.guid + ".png")
|
||||
)
|
||||
|
||||
bcfxml.add_viewpoint(topic, viewpoint)
|
||||
blender_render.filepath = old_filepath
|
||||
blender_render.image_settings.file_format = old_file_format
|
||||
props.refresh_topic(context)
|
||||
@@ -459,9 +495,15 @@ class RemoveBcfViewpoint(bpy.types.Operator):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
viewpoint_guid = blender_topic.viewpoints
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
bcfxml.delete_viewpoint(viewpoint_guid, topic)
|
||||
for key, viewpoint in topic.viewpoints.items():
|
||||
if viewpoint.guid == blender_topic.viewpoints:
|
||||
break
|
||||
del topic.viewpoints[key]
|
||||
for i, viewpoint in enumerate(topic.markup.viewpoints):
|
||||
if viewpoint.guid == blender_topic.viewpoints:
|
||||
break
|
||||
del topic.markup.viewpoints[i]
|
||||
props.refresh_topic(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -477,7 +519,7 @@ class RemoveBcfFile(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
bcfxml.delete_file(topic, self.index)
|
||||
del topic.header.file[self.index]
|
||||
props.refresh_topic(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -495,8 +537,7 @@ class RemoveBcfTopic(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
props = context.scene.BCFProperties
|
||||
topic_to_delete = props.active_topic
|
||||
bcfxml.delete_topic(topic_to_delete.name)
|
||||
del bcfxml.topics[props.active_topic.name]
|
||||
bpy.ops.bim.load_bcf_topics()
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -515,8 +556,7 @@ class AddBcfReferenceLink(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
topic.reference_links.append(props.reference_link)
|
||||
bcfxml.edit_topic(topic)
|
||||
topic.topic.reference_link.append(props.reference_link)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
props.reference_link = ""
|
||||
return {"FINISHED"}
|
||||
@@ -536,10 +576,23 @@ class AddBcfDocumentReference(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
document_reference = bcf.v2.data.DocumentReference()
|
||||
document_reference.referenced_document = props.document_reference
|
||||
document_reference.description = props.document_reference_description or None
|
||||
bcfxml.add_document_reference(topic, document_reference)
|
||||
|
||||
is_external = "://" in props.document_reference
|
||||
filename = Path(props.document_reference).name if os.path.exists(props.document_reference) else None
|
||||
|
||||
if filename:
|
||||
with open(props.document_reference, "rb") as f:
|
||||
topic.document_references[filename] = f.read()
|
||||
|
||||
document_reference = bcf.v2.model.TopicDocumentReference(
|
||||
referenced_document=props.document_reference if is_external else filename,
|
||||
description=props.document_reference_description or None,
|
||||
guid=str(uuid.uuid4()),
|
||||
is_external=is_external,
|
||||
)
|
||||
|
||||
topic.topic.document_reference.append(document_reference)
|
||||
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
props.document_reference = ""
|
||||
props.document_reference_description = ""
|
||||
@@ -562,8 +615,7 @@ class AddBcfLabel(bpy.types.Operator):
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
new = blender_topic.labels.add()
|
||||
new.name = props.label
|
||||
topic.labels.append(props.label)
|
||||
bcfxml.edit_topic(topic)
|
||||
topic.topic.labels.append(props.label)
|
||||
props.label = ""
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -578,11 +630,10 @@ class EditBcfReferenceLinks(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
for index, reference_link in enumerate(topic.reference_links):
|
||||
for index, reference_link in enumerate(topic.topic.reference_link):
|
||||
if reference_link == blender_topic.reference_links[index].name:
|
||||
continue
|
||||
topic.reference_links[index] = blender_topic.reference_links[index].name
|
||||
bcfxml.edit_topic(topic)
|
||||
topic.topic.reference_link[index] = blender_topic.reference_links[index].name
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -597,12 +648,11 @@ class EditBcfLabels(bpy.types.Operator):
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
for index, label in enumerate(blender_topic.labels):
|
||||
if index >= len(topic.labels):
|
||||
if index >= len(topic.topic.labels):
|
||||
break
|
||||
if label.name == topic.labels[index]:
|
||||
if label.name == topic.topic.labels[index]:
|
||||
continue
|
||||
topic.labels[index] = blender_topic.labels[index].name
|
||||
bcfxml.edit_topic(topic)
|
||||
topic.topic.labels[index] = blender_topic.labels[index].name
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -617,8 +667,7 @@ class RemoveBcfReferenceLink(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
del topic.reference_links[self.index]
|
||||
bcfxml.edit_topic(topic)
|
||||
del topic.topic.reference_link[self.index]
|
||||
blender_topic.reference_links.remove(self.index)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -634,8 +683,7 @@ class RemoveBcfLabel(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
del topic.labels[self.index]
|
||||
bcfxml.edit_topic(topic)
|
||||
del topic.topic.labels[self.index]
|
||||
blender_topic.labels.remove(self.index)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -650,7 +698,7 @@ class RemoveBcfBimSnippet(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
bcfxml.delete_bim_snippet(topic)
|
||||
topic.topic.bim_snippet = None
|
||||
blender_topic.bim_snippet.schema = ""
|
||||
blender_topic.bim_snippet.reference = ""
|
||||
blender_topic.bim_snippet.type = ""
|
||||
@@ -668,7 +716,7 @@ class RemoveBcfDocumentReference(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
bcfxml.delete_document_reference(topic, self.index)
|
||||
del topic.topic.document_reference[self.index]
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -684,8 +732,7 @@ class RemoveBcfRelatedTopic(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
del topic.related_topics[self.index]
|
||||
bcfxml.edit_topic(topic)
|
||||
del topic.topic.related_topic[self.index]
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -701,7 +748,10 @@ class RemoveBcfComment(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
bcfxml.delete_comment(self.comment_guid, topic)
|
||||
for i, comment in enumerate(topic.comments):
|
||||
if comment.guid == self.comment_guid:
|
||||
break
|
||||
del topic.comments[i]
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -718,9 +768,11 @@ class EditBcfComment(bpy.types.Operator):
|
||||
blender_topic = props.active_topic
|
||||
blender_comment = blender_topic.comments.get(self.comment_guid)
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
comment = topic.comments[self.comment_guid]
|
||||
comment.comment = blender_comment.comment
|
||||
bcfxml.edit_comment(comment, topic)
|
||||
for i, comment in enumerate(topic.comments):
|
||||
if comment.guid == self.comment_guid:
|
||||
comment.comment = blender_comment.comment
|
||||
comment.modified_date = XmlDateTime.now()
|
||||
comment.modified_author = context.scene.BCFProperties.author
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -745,12 +797,15 @@ class AddBcfComment(bpy.types.Operator):
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
comment = bcf.v2.data.Comment()
|
||||
comment.comment = props.comment
|
||||
comment = bcf.v2.model.Comment(
|
||||
date=XmlDateTime.now(),
|
||||
author=context.scene.BCFProperties.author,
|
||||
comment=props.comment,
|
||||
guid=str(uuid.uuid4()),
|
||||
)
|
||||
if props.has_related_viewpoint:
|
||||
comment.viewpoint = bcf.v2.data.Viewpoint()
|
||||
comment.viewpoint.guid = blender_topic.viewpoints
|
||||
bcfxml.add_comment(topic, comment)
|
||||
comment.viewpoint = bcf.v2.model.CommentViewpoint(guid=blender_topic.viewpoints)
|
||||
topic.comments.append(comment)
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||
props.comment = ""
|
||||
props.has_related_viewpoint = False
|
||||
@@ -791,11 +846,13 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
cam_height = context.scene.render.resolution_y
|
||||
cam_aspect = cam_width / cam_height
|
||||
|
||||
obj.data.background_images.clear()
|
||||
if viewpoint.snapshot:
|
||||
obj.data.show_background_images = True
|
||||
obj.data.background_images.clear()
|
||||
background = obj.data.background_images.new()
|
||||
background.image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, viewpoint.snapshot))
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
f.write(viewpoint.snapshot)
|
||||
background.image = bpy.data.images.load(f.name)
|
||||
src_width = background.image.size[0]
|
||||
src_height = background.image.size[1]
|
||||
src_aspect = src_width / src_height
|
||||
@@ -805,6 +862,9 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
else:
|
||||
background.frame_method = "CROP"
|
||||
background.display_depth = "FRONT"
|
||||
else:
|
||||
obj.data.show_background_images = False
|
||||
|
||||
area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
|
||||
area.spaces[0].region_3d.view_perspective = "CAMERA"
|
||||
|
||||
@@ -814,27 +874,27 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
gp = bpy.data.grease_pencils.get("BCF")
|
||||
if gp:
|
||||
bpy.data.grease_pencils.remove(gp)
|
||||
if viewpoint.lines:
|
||||
if viewpoint.visualization_info.lines:
|
||||
self.draw_lines(viewpoint, context)
|
||||
|
||||
self.delete_clipping_planes(context)
|
||||
if viewpoint.clipping_planes:
|
||||
if viewpoint.visualization_info.clipping_planes:
|
||||
self.create_clipping_planes(viewpoint)
|
||||
|
||||
self.delete_bitmaps(context)
|
||||
if viewpoint.bitmaps:
|
||||
if viewpoint.visualization_info.bitmap:
|
||||
self.create_bitmaps(bcfxml, viewpoint, topic)
|
||||
|
||||
self.setup_camera(viewpoint, obj, cam_aspect, context)
|
||||
return {"FINISHED"}
|
||||
|
||||
def setup_camera(self, viewpoint, obj, cam_aspect, context):
|
||||
if viewpoint.orthogonal_camera:
|
||||
camera = viewpoint.orthogonal_camera
|
||||
if viewpoint.visualization_info.orthogonal_camera:
|
||||
camera = viewpoint.visualization_info.orthogonal_camera
|
||||
obj.data.type = "ORTHO"
|
||||
obj.data.ortho_scale = viewpoint.orthogonal_camera.view_to_world_scale
|
||||
elif viewpoint.perspective_camera:
|
||||
camera = viewpoint.perspective_camera
|
||||
obj.data.ortho_scale = viewpoint.visualization_info.orthogonal_camera.view_to_world_scale
|
||||
elif viewpoint.visualization_info.perspective_camera:
|
||||
camera = viewpoint.visualization_info.perspective_camera
|
||||
obj.data.type = "PERSP"
|
||||
if cam_aspect >= 1:
|
||||
obj.data.angle = radians(camera.field_of_view)
|
||||
@@ -875,22 +935,22 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
obj.matrix_world = Matrix(matrix.tolist())
|
||||
|
||||
def set_viewpoint_components(self, viewpoint, context):
|
||||
if not viewpoint.components:
|
||||
if not viewpoint.visualization_info.components:
|
||||
return
|
||||
|
||||
# Operators with context overrides are used because they are
|
||||
# significantly faster than looping through all objects
|
||||
|
||||
exception_global_ids = {v.ifc_guid for v in viewpoint.components.visibility.exceptions}
|
||||
exception_global_ids = {v.ifc_guid for v in viewpoint.visualization_info.components.visibility.exceptions or []}
|
||||
|
||||
if viewpoint.components.visibility.default_visibility:
|
||||
if viewpoint.visualization_info.components.visibility.default_visibility:
|
||||
old = context.area.type
|
||||
context.area.type = "VIEW_3D"
|
||||
bpy.ops.object.hide_view_clear()
|
||||
context.area.type = old
|
||||
for global_id in exception_global_ids:
|
||||
obj = IfcStore.get_element(global_id)
|
||||
if obj:
|
||||
if obj and bpy.context.view_layer.objects.get(obj.name):
|
||||
obj.hide_set(True)
|
||||
else:
|
||||
objs = []
|
||||
@@ -907,11 +967,13 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
bpy.ops.object.hide_view_set(context_override, unselected=True)
|
||||
context.area.type = old
|
||||
|
||||
if viewpoint.components.view_setup_hints:
|
||||
if not viewpoint.components.view_setup_hints.spaces_visible:
|
||||
if viewpoint.visualization_info.components.view_setup_hints:
|
||||
if not viewpoint.visualization_info.components.view_setup_hints.spaces_visible:
|
||||
self.hide_spaces(context)
|
||||
if viewpoint.components.view_setup_hints.openings_visible is not None:
|
||||
self.set_openings_visibility(viewpoint.components.view_setup_hints.openings_visible, context)
|
||||
if viewpoint.visualization_info.components.view_setup_hints.openings_visible is not None:
|
||||
self.set_openings_visibility(
|
||||
viewpoint.visualization_info.components.view_setup_hints.openings_visible, context
|
||||
)
|
||||
else:
|
||||
self.hide_spaces(context)
|
||||
self.set_openings_visibility(False, context)
|
||||
@@ -927,11 +989,12 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
context.area.type = old
|
||||
|
||||
def set_openings_visibility(self, is_visible, context):
|
||||
for collection in self.get_opening_collections(context):
|
||||
collection.hide_viewport = not is_visible
|
||||
pass # We no longer have an openings collection
|
||||
|
||||
def set_selection(self, viewpoint):
|
||||
selected_global_ids = [s.ifc_guid for s in viewpoint.components.selection]
|
||||
if not viewpoint.visualization_info.components or not viewpoint.visualization_info.components.selection:
|
||||
return
|
||||
selected_global_ids = [s.ifc_guid for s in viewpoint.visualization_info.components.selection.component or []]
|
||||
bpy.ops.object.select_all(action="DESELECT")
|
||||
for global_id in selected_global_ids:
|
||||
obj = IfcStore.get_element(global_id)
|
||||
@@ -940,7 +1003,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
|
||||
def set_colours(self, viewpoint):
|
||||
global_id_colours = {}
|
||||
for coloring in viewpoint.components.coloring:
|
||||
for coloring in viewpoint.visualization_info.components.coloring or []:
|
||||
for component in coloring.components:
|
||||
global_id_colours.setdefault(component.ifc_guid, coloring.color)
|
||||
for global_id, color in global_id_colours.items():
|
||||
@@ -948,14 +1011,6 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
if obj:
|
||||
obj.color = self.hex_to_rgb(color)
|
||||
|
||||
def get_opening_collections(self, context):
|
||||
collections = []
|
||||
for collection in context.view_layer.layer_collection.children:
|
||||
opening_collection = collection.children.get("IfcOpeningElements")
|
||||
if opening_collection:
|
||||
collections.append(opening_collection)
|
||||
return collections
|
||||
|
||||
def draw_lines(self, viewpoint, context):
|
||||
gp = bpy.data.grease_pencils.new("BCF")
|
||||
scene = context.scene
|
||||
@@ -967,9 +1022,9 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
frame = layer.frames.new(1)
|
||||
stroke = frame.strokes.new()
|
||||
stroke.display_mode = "3DSPACE"
|
||||
stroke.points.add(len(viewpoint.lines) * 2)
|
||||
stroke.points.add(len(viewpoint.visualization_info.lines.line) * 2)
|
||||
coords = []
|
||||
for l in viewpoint.lines:
|
||||
for l in viewpoint.visualization_info.lines.line:
|
||||
coords.extend(
|
||||
[l.start_point.x, l.start_point.y, l.start_point.z, l.end_point.x, l.end_point.y, l.end_point.z]
|
||||
)
|
||||
@@ -977,7 +1032,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
|
||||
def create_clipping_planes(self, viewpoint):
|
||||
n = 0
|
||||
for plane in viewpoint.clipping_planes:
|
||||
for plane in viewpoint.visualization_info.clipping_planes.clipping_plane:
|
||||
bpy.ops.bim.add_section_plane()
|
||||
if n == 0:
|
||||
obj = bpy.data.objects["Section"]
|
||||
@@ -1010,10 +1065,14 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
collection = bpy.data.collections.get("Bitmaps")
|
||||
if not collection:
|
||||
collection = bpy.data.collections.new("Bitmaps")
|
||||
for bitmap in viewpoint.bitmaps:
|
||||
for bitmap in viewpoint.visualization_info.bitmap:
|
||||
obj = bpy.data.objects.new("Bitmap", None)
|
||||
obj.empty_display_type = "IMAGE"
|
||||
image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, bitmap.reference))
|
||||
# image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, bitmap.reference))
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
topic.extract_file(bitmap, f.name)
|
||||
# f.write(bitmap.what)
|
||||
image = bpy.data.images.load(f.name)
|
||||
src_width = image.size[0]
|
||||
src_height = image.size[1]
|
||||
if src_height > src_width:
|
||||
@@ -1052,6 +1111,7 @@ class SelectBcfHeaderFile(bpy.types.Operator):
|
||||
bl_label = "Select BCF Header File"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
filter_glob: bpy.props.StringProperty(default="*.ifc;*.ifczip;*.ifcxml;*.ifcjson", options={"HIDDEN"})
|
||||
|
||||
def execute(self, context):
|
||||
if self.filepath:
|
||||
@@ -1093,3 +1153,25 @@ class SelectBcfDocumentReference(bpy.types.Operator):
|
||||
def invoke(self, context, event):
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
|
||||
class ExtractBcfFile(bpy.types.Operator):
|
||||
bl_idname = "bim.extract_bcf_file"
|
||||
bl_label = "Extract BCF Header File"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
entity_type: bpy.props.StringProperty()
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
topic = bcfxml.topics[context.scene.BCFProperties.active_topic.name]
|
||||
|
||||
if self.entity_type == "HEADER_FILE":
|
||||
entity = topic.header.file[self.index]
|
||||
elif self.entity_type == "BIM_SNIPPET":
|
||||
entity = topic.markup.topic.bim_snippet
|
||||
elif self.entity_type == "DOCUMENT_REFERENCE":
|
||||
entity = topic.markup.topic.document_reference[self.index]
|
||||
|
||||
webbrowser.open(str(topic.extract_file(entity).parent))
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -95,8 +95,8 @@ def getBcfViewpoints(self, context, force_update=False):
|
||||
props = context.scene.BCFProperties
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
topic = props.active_topic
|
||||
viewpoints = bcfxml.get_viewpoints(topic.name) if topic else {}
|
||||
bcfviewpoints_enum.extend([(v, f"Viewpoint {i+1}", "") for i, v in enumerate(viewpoints.keys())])
|
||||
viewpoints = bcfxml.topics[topic.name].viewpoints.keys() if topic else []
|
||||
bcfviewpoints_enum.extend([(v, f"Viewpoint {i+1}", "") for i, v in enumerate(viewpoints)])
|
||||
return bcfviewpoints_enum
|
||||
|
||||
|
||||
|
||||
@@ -39,14 +39,16 @@ class BIM_PT_bcf(Panel):
|
||||
scene = context.scene
|
||||
props = scene.BCFProperties
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.new_bcf_project", text="New Project")
|
||||
row.operator("bim.load_bcf_project", text="Load Project")
|
||||
|
||||
if not props.is_loaded:
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.new_bcf_project", text="New Project")
|
||||
row.operator("bim.load_bcf_project", text="Load Project")
|
||||
return
|
||||
|
||||
row.operator("bim.save_bcf_project", text="Save Project")
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.save_bcf_project", icon="EXPORT", text="Save Project")
|
||||
row.operator("bim.unload_bcf_project", text="", icon="CANCEL")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, "name")
|
||||
@@ -127,20 +129,21 @@ class BIM_PT_bcf_metadata(Panel):
|
||||
layout.label(text="Header Files:")
|
||||
|
||||
if bcf_topic.header:
|
||||
for index, f in enumerate(bcf_topic.header.files):
|
||||
for index, f in enumerate(bcf_topic.header.file):
|
||||
box = self.layout.box()
|
||||
row = box.row(align=True)
|
||||
row.label(text=f.filename, icon="FILE_BLANK")
|
||||
if f.is_external:
|
||||
row.operator("bim.open_uri", icon="URL", text="").uri = f.reference
|
||||
else:
|
||||
op = row.operator("bim.open_uri", icon="FILE_FOLDER", text="")
|
||||
op.uri = os.path.join(bcfxml.filepath, topic.name, f.reference)
|
||||
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
||||
op.index = index
|
||||
op.entity_type = "HEADER_FILE"
|
||||
row.operator("bim.remove_bcf_file", icon="X", text="").index = index
|
||||
|
||||
row = box.row()
|
||||
row.label(text="Date")
|
||||
row.label(text=f.date)
|
||||
row.label(text=str(f.date))
|
||||
|
||||
if f.ifc_project:
|
||||
row = box.row()
|
||||
@@ -196,8 +199,8 @@ class BIM_PT_bcf_metadata(Panel):
|
||||
if topic.bim_snippet.is_external:
|
||||
row.operator("bim.open_uri", icon="URL", text="").uri = topic.bim_snippet.reference
|
||||
else:
|
||||
op = row.operator("bim.open_uri", icon="FILE_FOLDER", text="")
|
||||
op.uri = os.path.join(bcfxml.filepath, topic.name, topic.bim_snippet.reference)
|
||||
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
||||
op.entity_type = "BIM_SNIPPET"
|
||||
row.operator("bim.remove_bcf_bim_snippet", icon="X", text="")
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
@@ -218,8 +221,10 @@ class BIM_PT_bcf_metadata(Panel):
|
||||
if doc.is_external:
|
||||
row.operator("bim.open_uri", icon="URL", text="").uri = doc.reference
|
||||
else:
|
||||
op = row.operator("bim.open_uri", icon="FILE_FOLDER", text="")
|
||||
op.uri = os.path.join(bcfxml.filepath, topic.name, doc.reference)
|
||||
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
||||
op.entity_type = "DOCUMENT_REFERENCE"
|
||||
op.index = index
|
||||
|
||||
row.operator("bim.remove_bcf_document_reference", icon="X", text="").index = index
|
||||
row = box.row(align=True)
|
||||
row.prop(doc, "description")
|
||||
@@ -236,7 +241,7 @@ class BIM_PT_bcf_metadata(Panel):
|
||||
try:
|
||||
row = layout.row(align=True)
|
||||
op = row.operator(
|
||||
"bim.view_bcf_topic", text=f"Select {bcfxml.topics[related_topic.name.lower()].title}"
|
||||
"bim.view_bcf_topic", text=f"Select {bcfxml.topics[related_topic.name.lower()].topic.title}"
|
||||
)
|
||||
op.topic_guid = related_topic.name
|
||||
row.operator("bim.remove_bcf_related_topic", icon="X", text="").index = index
|
||||
|
||||
@@ -20,25 +20,37 @@ import bpy
|
||||
from . import ui, operator, prop
|
||||
|
||||
classes = (
|
||||
operator.AddBoundary,
|
||||
operator.ColourByRelatedBuildingElement,
|
||||
operator.DisableEditingBoundary,
|
||||
operator.DisableEditingBoundaryGeometry,
|
||||
operator.EditBoundaryAttributes,
|
||||
operator.EditBoundaryGeometry,
|
||||
operator.EnableEditingBoundary,
|
||||
operator.EnableEditingBoundaryGeometry,
|
||||
operator.HideBoundaries,
|
||||
operator.LoadBoundary,
|
||||
operator.LoadProjectSpaceBoundaries,
|
||||
operator.LoadSpaceBoundaries,
|
||||
operator.LoadBoundary,
|
||||
operator.SelectProjectBoundaries,
|
||||
operator.ColourByRelatedBuildingElement,
|
||||
operator.EnableEditingBoundary,
|
||||
operator.DisableEditingBoundary,
|
||||
operator.EditBoundaryAttributes,
|
||||
operator.SelectRelatedElementBoundaries,
|
||||
operator.SelectRelatedElementTypeBoundaries,
|
||||
operator.SelectSpaceBoundaries,
|
||||
operator.ShowBoundaries,
|
||||
operator.UpdateBoundaryGeometry,
|
||||
ui.BIM_PT_Boundary,
|
||||
ui.BIM_PT_SpaceBoundaries,
|
||||
ui.BIM_PT_SceneBoundaries,
|
||||
ui.BIM_PT_SpaceBoundaries,
|
||||
prop.BIMBoundaryProperties,
|
||||
prop.BIMObjectBoundaryProperties,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.Object.bim_boundary_properties = bpy.props.PointerProperty(type=prop.BIMBoundaryProperties)
|
||||
bpy.types.Scene.BIMBoundaryProperties = bpy.props.PointerProperty(type=prop.BIMBoundaryProperties)
|
||||
bpy.types.Object.bim_boundary_properties = bpy.props.PointerProperty(type=prop.BIMObjectBoundaryProperties)
|
||||
|
||||
|
||||
def unregister():
|
||||
del bpy.types.Scene.BIMBoundaryProperties
|
||||
del bpy.types.Object.bim_boundary_properties
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2023 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# 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 bpy
|
||||
import blenderbim.tool as tool
|
||||
|
||||
|
||||
def refresh():
|
||||
SpaceBoundariesData.is_loaded = False
|
||||
|
||||
|
||||
class SpaceBoundariesData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.data = {"boundaries": cls.boundaries()}
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def boundaries(cls):
|
||||
results = []
|
||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
for rel in element.BoundedBy or []:
|
||||
description = f"{rel.id()} > {rel.RelatedBuildingElement.is_a()}/{rel.RelatedBuildingElement.Name}"
|
||||
results.append({"id": rel.id(), "description": description})
|
||||
return results
|
||||
@@ -0,0 +1,112 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2023 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# 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 gpu
|
||||
import bmesh
|
||||
import blenderbim.tool as tool
|
||||
from bpy.types import SpaceView3D
|
||||
from mathutils import Vector
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
|
||||
class BoundaryDecorator:
|
||||
installed = None
|
||||
|
||||
@classmethod
|
||||
def install(cls, context):
|
||||
if cls.installed:
|
||||
cls.uninstall()
|
||||
handler = cls()
|
||||
cls.installed = SpaceView3D.draw_handler_add(handler, (context,), "WINDOW", "POST_VIEW")
|
||||
|
||||
@classmethod
|
||||
def uninstall(cls):
|
||||
try:
|
||||
SpaceView3D.draw_handler_remove(cls.installed, "WINDOW")
|
||||
except ValueError:
|
||||
pass
|
||||
cls.installed = None
|
||||
|
||||
def draw_batch(self, shader_type, content_pos, color, indices=None):
|
||||
shader = self.line_shader if shader_type == "LINES" else self.shader
|
||||
batch = batch_for_shader(shader, shader_type, {"pos": content_pos}, indices=indices)
|
||||
shader.uniform_float("color", color)
|
||||
batch.draw(shader)
|
||||
|
||||
def __call__(self, context):
|
||||
self.addon_prefs = context.preferences.addons["blenderbim"].preferences
|
||||
selected_elements_color = self.addon_prefs.decorator_color_selected
|
||||
unselected_elements_color = self.addon_prefs.decorator_color_unselected
|
||||
special_elements_color = self.addon_prefs.decorator_color_special
|
||||
|
||||
def transparent_color(color, alpha=0.1):
|
||||
color = [i for i in color]
|
||||
color[3] = alpha
|
||||
return color
|
||||
|
||||
gpu.state.point_size_set(6)
|
||||
gpu.state.blend_set("ALPHA")
|
||||
|
||||
self.line_shader = gpu.shader.from_builtin("3D_POLYLINE_UNIFORM_COLOR")
|
||||
self.line_shader.bind() # required to be able to change uniforms of the shader
|
||||
# POLYLINE_UNIFORM_COLOR specific uniforms
|
||||
self.line_shader.uniform_float("viewportSize", (context.region.width, context.region.height))
|
||||
self.line_shader.uniform_float("lineWidth", 2.0)
|
||||
|
||||
# general shader
|
||||
self.shader = gpu.shader.from_builtin("3D_UNIFORM_COLOR")
|
||||
|
||||
selected_vertices = []
|
||||
selected_edges = []
|
||||
selected_tris = []
|
||||
unselected_vertices = []
|
||||
unselected_edges = []
|
||||
unselected_tris = []
|
||||
|
||||
for boundary in context.scene.BIMBoundaryProperties.boundaries:
|
||||
obj = boundary.obj
|
||||
if not obj or not obj.data: # A boundary may not have data if it has no connection geometry
|
||||
continue
|
||||
|
||||
if obj.mode == "EDIT":
|
||||
continue # A profile decorator or something else is used here.
|
||||
else:
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(obj.data)
|
||||
obj.data.calc_loop_triangles()
|
||||
|
||||
if obj.select_get():
|
||||
offset = len(selected_vertices)
|
||||
selected_vertices.extend([tuple(obj.matrix_world @ v.co) for v in bm.verts])
|
||||
selected_edges.extend([tuple([v.index + offset for v in e.verts]) for e in bm.edges])
|
||||
selected_tris.extend([tuple([i + offset for i in t.vertices]) for t in obj.data.loop_triangles])
|
||||
else:
|
||||
offset = len(unselected_vertices)
|
||||
unselected_vertices.extend([tuple(obj.matrix_world @ v.co) for v in bm.verts])
|
||||
unselected_edges.extend([tuple([v.index + offset for v in e.verts]) for e in bm.edges])
|
||||
unselected_tris.extend([tuple([i + offset for i in t.vertices]) for t in obj.data.loop_triangles])
|
||||
|
||||
if obj.mode != "EDIT":
|
||||
bm.free()
|
||||
|
||||
if unselected_edges:
|
||||
self.draw_batch("LINES", unselected_vertices, special_elements_color, unselected_edges)
|
||||
self.draw_batch("TRIS", unselected_vertices, transparent_color(special_elements_color), unselected_tris)
|
||||
if selected_edges:
|
||||
self.draw_batch("LINES", selected_vertices, selected_elements_color, selected_edges)
|
||||
self.draw_batch("TRIS", selected_vertices, transparent_color(selected_elements_color), selected_tris)
|
||||
@@ -17,16 +17,29 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bmesh
|
||||
import logging
|
||||
import shapely
|
||||
import mathutils
|
||||
import numpy as np
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.shape
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import blenderbim.tool as tool
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.boundary.data import Data
|
||||
import blenderbim.bim.import_ifc as import_ifc
|
||||
from math import pi, inf
|
||||
from mathutils import Vector, Matrix
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.model.decorator import ProfileDecorator
|
||||
from blenderbim.bim.module.boundary.decorator import BoundaryDecorator
|
||||
import blenderbim.core
|
||||
|
||||
|
||||
def get_boundaries_collection(blender_space):
|
||||
space_collection = bpy.data.collections.get(blender_space.name, blender_space.users_collection[0])
|
||||
space_collection = blender_space.BIMObjectProperties.collection
|
||||
collection_name = f"Boundaries/{blender_space.BIMObjectProperties.ifc_definition_id}"
|
||||
boundaries_collection = space_collection.children.get(collection_name)
|
||||
if not boundaries_collection:
|
||||
@@ -35,13 +48,27 @@ def get_boundaries_collection(blender_space):
|
||||
return boundaries_collection
|
||||
|
||||
|
||||
def disable_editing_boundary_geometry(context):
|
||||
ProfileDecorator.uninstall()
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
|
||||
obj = context.active_object
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
|
||||
old_mesh = obj.data
|
||||
loader = Loader()
|
||||
obj.data = loader.create_mesh(element)
|
||||
tool.Geometry.delete_data(old_mesh)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class Loader:
|
||||
def __init__(self):
|
||||
self.ifc_file = None
|
||||
self.logger = None
|
||||
self.ifc_importer = None
|
||||
self.settings = None
|
||||
self.load_settings()
|
||||
self.settings = self.load_settings()
|
||||
self.fallback_settings = self.load_fallback_settings()
|
||||
self.load_importer()
|
||||
|
||||
def create_mesh(self, boundary):
|
||||
@@ -49,18 +76,50 @@ class Loader:
|
||||
if not boundary.ConnectionGeometry:
|
||||
return None
|
||||
surface = boundary.ConnectionGeometry.SurfaceOnRelatingElement
|
||||
# workaround for invalid geometry provided by Revit. See https://github.com/IfcOpenShell/IfcOpenShell/issues/635#issuecomment-770366838
|
||||
# Workaround for invalid geometry provided by Revit. See https://github.com/Autodesk/revit-ifc/issues/270
|
||||
if surface.is_a("IfcCurveBoundedPlane") and not getattr(surface, "InnerBoundaries", None):
|
||||
surface.InnerBoundaries = ()
|
||||
shape = ifcopenshell.geom.create_shape(self.settings, surface)
|
||||
mesh = self.ifc_importer.create_mesh(None, shape)
|
||||
self.ifc_importer.link_mesh(shape, mesh)
|
||||
try:
|
||||
shape = ifcopenshell.geom.create_shape(self.settings, surface)
|
||||
mesh = self.ifc_importer.create_mesh(None, shape)
|
||||
tool.Loader.link_mesh(shape, mesh)
|
||||
except RuntimeError:
|
||||
# Fallback solution for invalid geometry provided by Revit. (InnerBoundaries cuting OuterBoundary)
|
||||
print(f"Failed to create mesh from IfcRelSpaceBoundary with ID {boundary.id()}. Geometry might be invalid")
|
||||
shape = ifcopenshell.geom.create_shape(self.fallback_settings, surface.OuterBoundary)
|
||||
mesh = bpy.data.meshes.new(str(surface.id()))
|
||||
bm = bmesh.new()
|
||||
verts = [bm.verts.new(shape.verts[i : i + 3]) for i in range(0, len(shape.verts), 3)]
|
||||
bm.faces.new(verts)
|
||||
for inner_boundary in surface.InnerBoundaries:
|
||||
shape = ifcopenshell.geom.create_shape(self.fallback_settings, inner_boundary)
|
||||
verts = [bm.verts.new(shape.verts[i : i + 3]) for i in range(0, len(shape.verts), 3)]
|
||||
for i in range(len(verts) - 1):
|
||||
bm.edges.new(verts[i : i + 2])
|
||||
bm.edges.new((verts[-1], verts[0]))
|
||||
bm.to_mesh(mesh)
|
||||
bm.free()
|
||||
mesh.BIMMeshProperties.ifc_definition_id = surface.id()
|
||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
matrix = mathutils.Matrix(
|
||||
ifcopenshell.util.placement.get_axis2placement(surface.BasisSurface.Position).tolist()
|
||||
)
|
||||
matrix[0][3] *= unit_scale
|
||||
matrix[1][3] *= unit_scale
|
||||
matrix[2][3] *= unit_scale
|
||||
mesh.transform(matrix)
|
||||
return mesh
|
||||
|
||||
def load_settings(self):
|
||||
self.settings = ifcopenshell.geom.settings()
|
||||
self.settings.set(self.settings.EXCLUDE_SOLIDS_AND_SURFACES, False)
|
||||
self.settings.set(self.settings.USE_BREP_DATA, False)
|
||||
settings = ifcopenshell.geom.settings()
|
||||
settings.set(settings.EXCLUDE_SOLIDS_AND_SURFACES, False)
|
||||
settings.set(settings.USE_BREP_DATA, False)
|
||||
return settings
|
||||
|
||||
def load_fallback_settings(self):
|
||||
settings = ifcopenshell.geom.settings()
|
||||
settings.set(settings.INCLUDE_CURVES, True)
|
||||
return settings
|
||||
|
||||
def load_importer(self):
|
||||
self.ifc_file = tool.Ifc.get()
|
||||
@@ -69,8 +128,7 @@ class Loader:
|
||||
self.ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
|
||||
self.ifc_importer.file = self.ifc_file
|
||||
|
||||
def load_boundary(self, boundary_id, blender_space):
|
||||
boundary = self.ifc_file.by_id(boundary_id)
|
||||
def load_boundary(self, boundary, blender_space):
|
||||
obj = tool.Ifc.get_object(boundary)
|
||||
if obj:
|
||||
return obj
|
||||
@@ -85,32 +143,27 @@ class Loader:
|
||||
|
||||
class LoadProjectSpaceBoundaries(bpy.types.Operator):
|
||||
bl_idname = "bim.load_project_space_boundaries"
|
||||
bl_label = "Load all project space boundaries"
|
||||
bl_label = "Load All Project Space Boundaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
loader = Loader()
|
||||
if not Data.is_loaded:
|
||||
Data.load(tool.Ifc.get())
|
||||
for space_id, boundaries_id in Data.spaces.items():
|
||||
blender_space = tool.Ifc.get_object(tool.Ifc.get().by_id(space_id))
|
||||
for boundary_id in boundaries_id:
|
||||
loader.load_boundary(boundary_id, blender_space)
|
||||
for rel in tool.Ifc.get().by_type("IfcRelSpaceBoundary"):
|
||||
loader.load_boundary(rel, tool.Ifc.get_object(rel.RelatingSpace))
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class LoadBoundary(bpy.types.Operator):
|
||||
bl_idname = "bim.load_boundary"
|
||||
bl_label = "Load boundary"
|
||||
bl_label = "Load Boundary"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
boundary_id: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
loader = Loader()
|
||||
blender_space = context.active_object
|
||||
for obj in context.visible_objects:
|
||||
obj.select_set(False)
|
||||
obj = loader.load_boundary(self.boundary_id, blender_space)
|
||||
obj = loader.load_boundary(tool.Ifc.get().by_id(self.boundary_id), context.active_object)
|
||||
obj.select_set(True)
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
return {"FINISHED"}
|
||||
@@ -118,32 +171,91 @@ class LoadBoundary(bpy.types.Operator):
|
||||
|
||||
class LoadSpaceBoundaries(bpy.types.Operator):
|
||||
bl_idname = "bim.load_space_boundaries"
|
||||
bl_label = "Load selected space boundaries"
|
||||
bl_label = "Load Selected Space Boundaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
blender_space = context.active_object
|
||||
oprops = context.active_object.BIMObjectProperties
|
||||
loader = Loader()
|
||||
if not Data.is_loaded:
|
||||
Data.load(tool.Ifc.get())
|
||||
for boundary_id in Data.spaces.get(oprops.ifc_definition_id, []):
|
||||
loader.load_boundary(boundary_id, blender_space)
|
||||
element = tool.Ifc.get_entity(context.active_object)
|
||||
for rel in element.BoundedBy or []:
|
||||
loader.load_boundary(rel, context.active_object)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SelectProjectBoundaries(bpy.types.Operator):
|
||||
bl_idname = "bim.select_project_space_boundaries"
|
||||
bl_label = "Select all project space boundaries"
|
||||
def get_element_boundaries(element):
|
||||
if not element:
|
||||
return ()
|
||||
if element.is_a("IfcSpace"):
|
||||
return (b for b in element.BoundedBy or ())
|
||||
return (b for b in element.ProvidesBoundaries)
|
||||
|
||||
|
||||
class SelectRelatedElementBoundaries(bpy.types.Operator):
|
||||
bl_idname = "bim.select_related_element_boundaries"
|
||||
bl_label = "Select Related Element Space Boundaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
related_element: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
for obj in context.visible_objects:
|
||||
obj.select_set(False)
|
||||
element = tool.Ifc.get().by_id(self.related_element)
|
||||
for rel in get_element_boundaries(element):
|
||||
obj = tool.Ifc.get_object(rel)
|
||||
if obj:
|
||||
obj.select_set(True)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SelectRelatedElementTypeBoundaries(bpy.types.Operator):
|
||||
bl_idname = "bim.select_related_element_type_boundaries"
|
||||
bl_label = "Select Related Element Type Space Boundaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
related_element: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
for obj in context.visible_objects:
|
||||
obj.select_set(False)
|
||||
element = tool.Ifc.get().by_id(self.related_element)
|
||||
if not element:
|
||||
return {"FINISHED"}
|
||||
element_type = tool.Root.get_element_type(element)
|
||||
if not element_type:
|
||||
return {"FINISHED"}
|
||||
for child in tool.Type.get_type_occurrences(element_type):
|
||||
for rel in get_element_boundaries(child):
|
||||
obj = tool.Ifc.get_object(rel)
|
||||
if obj:
|
||||
obj.select_set(True)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SelectSpaceBoundaries(bpy.types.Operator):
|
||||
bl_idname = "bim.select_space_boundaries"
|
||||
bl_label = "Select All Space Boundaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
for obj in context.visible_objects:
|
||||
obj.select_set(False)
|
||||
ifc_file = tool.Ifc.get()
|
||||
for boundary_id in Data.boundaries:
|
||||
boundary = ifc_file.by_id(boundary_id)
|
||||
obj = tool.Ifc.get_object(boundary)
|
||||
element = tool.Ifc.get_entity(context.active_object)
|
||||
for rel in element.BoundedBy or []:
|
||||
obj = tool.Ifc.get_object(rel)
|
||||
if obj:
|
||||
obj.select_set(True)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SelectProjectBoundaries(bpy.types.Operator):
|
||||
bl_idname = "bim.select_project_space_boundaries"
|
||||
bl_label = "Select All Project Space Boundaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
for obj in context.visible_objects:
|
||||
obj.select_set(False)
|
||||
for rel in tool.Ifc.get().by_type("IfcRelSpaceBoundary"):
|
||||
obj = tool.Ifc.get_object(rel)
|
||||
if obj:
|
||||
obj.select_set(True)
|
||||
return {"FINISHED"}
|
||||
@@ -172,7 +284,7 @@ def get_colour(ifc_boundary):
|
||||
|
||||
class ColourByRelatedBuildingElement(bpy.types.Operator):
|
||||
bl_idname = "bim.colour_by_related_building_element"
|
||||
bl_label = "Apply colour based on related building elements"
|
||||
bl_label = "Apply Colour Based on Related Building Elements"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
@@ -184,11 +296,10 @@ class ColourByRelatedBuildingElement(bpy.types.Operator):
|
||||
return result
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = tool.Ifc.get()
|
||||
for obj in context.visible_objects:
|
||||
if not obj.BIMObjectProperties.ifc_definition_id:
|
||||
continue
|
||||
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element.is_a("IfcRelSpaceBoundary"):
|
||||
continue
|
||||
obj.color = get_colour(element)
|
||||
@@ -221,7 +332,7 @@ EDITABLE_ATTRIBUTES = {
|
||||
|
||||
class EnableEditingBoundary(bpy.types.Operator):
|
||||
bl_idname = "bim.enable_editing_boundary"
|
||||
bl_label = "Edit boundary relations"
|
||||
bl_label = "Edit Boundary Relations"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
@@ -240,7 +351,7 @@ class EnableEditingBoundary(bpy.types.Operator):
|
||||
|
||||
class DisableEditingBoundary(bpy.types.Operator):
|
||||
bl_idname = "bim.disable_editing_boundary"
|
||||
bl_label = "Disable editing boundary relations"
|
||||
bl_label = "Disable Editing Boundary Relations"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
@@ -253,7 +364,7 @@ class DisableEditingBoundary(bpy.types.Operator):
|
||||
|
||||
class EditBoundaryAttributes(bpy.types.Operator):
|
||||
bl_idname = "bim.edit_boundary_attributes"
|
||||
bl_label = "Disable editing boundary relations"
|
||||
bl_label = "Disable Editing Boundary Relations"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
@@ -274,7 +385,7 @@ class EditBoundaryAttributes(bpy.types.Operator):
|
||||
|
||||
class UpdateBoundaryGeometry(bpy.types.Operator):
|
||||
bl_idname = "bim.update_boundary_geometry"
|
||||
bl_label = "Update boundary geometry"
|
||||
bl_label = "Update Boundary Geometry"
|
||||
bl_description = """
|
||||
Update boundary connection geometry from mesh.
|
||||
Mesh must lie on a single plane. It should look like a face or a face with holes.
|
||||
@@ -285,6 +396,361 @@ class UpdateBoundaryGeometry(bpy.types.Operator):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
tool.Boundary.move_origin_to_space_origin(context.active_object)
|
||||
settings = tool.Boundary.get_assign_connection_geometry_settings(context.active_object)
|
||||
ifcopenshell.api.run("boundary.assign_connection_geometry", tool.Ifc.get(), **settings)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EnableEditingBoundaryGeometry(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.enable_editing_boundary_geometry"
|
||||
bl_label = "Enable Editing Boundary Geometry"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.selected_objects
|
||||
|
||||
def _execute(self, context):
|
||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
obj = context.active_object
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
|
||||
if element.ConnectionGeometry.is_a("IfcConnectionSurfaceGeometry"):
|
||||
surface = element.ConnectionGeometry.SurfaceOnRelatingElement
|
||||
tool.Model.import_surface(surface, obj)
|
||||
|
||||
bpy.ops.object.mode_set(mode="EDIT")
|
||||
ProfileDecorator.install(context, exit_edit_mode_callback=lambda: disable_editing_boundary_geometry(context))
|
||||
if not bpy.app.background:
|
||||
bpy.ops.wm.tool_set_by_id(tool.Blender.get_viewport_context(), name="bim.cad_tool")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EditBoundaryGeometry(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.edit_boundary_geometry"
|
||||
bl_label = "Edit Boundary Geometry"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
ProfileDecorator.uninstall()
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
|
||||
obj = context.active_object
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
|
||||
if element.ConnectionGeometry.is_a("IfcConnectionSurfaceGeometry"):
|
||||
surface = tool.Model.export_surface(obj)
|
||||
|
||||
if not surface:
|
||||
|
||||
def msg(self, context):
|
||||
self.layout.label(text="INVALID PROFILE")
|
||||
|
||||
bpy.context.window_manager.popup_menu(msg, title="Error", icon="ERROR")
|
||||
ProfileDecorator.install(
|
||||
context, exit_edit_mode_callback=lambda: disable_editing_boundary_geometry(context)
|
||||
)
|
||||
bpy.ops.object.mode_set(mode="EDIT")
|
||||
return
|
||||
|
||||
old_surface = element.ConnectionGeometry.SurfaceOnRelatingElement
|
||||
for inverse in tool.Ifc.get().get_inverse(old_surface):
|
||||
ifcopenshell.util.element.replace_attribute(inverse, old_surface, surface)
|
||||
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_surface)
|
||||
|
||||
old_mesh = obj.data
|
||||
loader = Loader()
|
||||
obj.data = loader.create_mesh(element)
|
||||
tool.Geometry.delete_data(old_mesh)
|
||||
|
||||
|
||||
class DisableEditingBoundaryGeometry(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.disable_editing_boundary_geometry"
|
||||
bl_label = "Disable Editing Boundary Geometry"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.selected_objects
|
||||
|
||||
def _execute(self, context):
|
||||
return disable_editing_boundary_geometry(context)
|
||||
|
||||
|
||||
class ShowBoundaries(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.show_boundaries"
|
||||
bl_label = "Show Boundaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMBoundaryProperties
|
||||
loader = Loader()
|
||||
for obj in context.selected_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element or not getattr(element, "BoundedBy", None):
|
||||
continue
|
||||
if tool.Ifc.is_moved(obj):
|
||||
blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
for rel in element.BoundedBy or []:
|
||||
boundary_obj = loader.load_boundary(rel, obj)
|
||||
tool.Boundary.decorate_boundary(boundary_obj)
|
||||
BoundaryDecorator.install(bpy.context)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class HideBoundaries(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.hide_boundaries"
|
||||
bl_label = "Hide Boundaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
to_delete = set()
|
||||
spaces = set()
|
||||
for obj in context.selected_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
continue
|
||||
if element.is_a("IfcSpace"):
|
||||
spaces.add(element)
|
||||
elif element.is_a("IfcRelSpaceBoundary"):
|
||||
spaces.add(element.RelatingSpace)
|
||||
|
||||
for element in spaces:
|
||||
for boundary in element.BoundedBy or []:
|
||||
boundary_obj = tool.Ifc.get_object(boundary)
|
||||
if boundary_obj:
|
||||
to_delete.add(boundary_obj)
|
||||
for boundary_obj in to_delete:
|
||||
tool.Ifc.unlink(obj=boundary_obj)
|
||||
bpy.data.objects.remove(boundary_obj)
|
||||
context.scene.BIMBoundaryProperties.boundaries.clear()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_boundary"
|
||||
bl_label = "Add Boundary"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
relating_space = None
|
||||
related_building_element = None
|
||||
relating_space_obj = None
|
||||
related_building_element_obj = None
|
||||
|
||||
objs = context.selected_objects
|
||||
if len(objs) == 2:
|
||||
# The user may select two objects, a space and its related building element
|
||||
for obj in objs:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
continue
|
||||
if element.is_a("IfcSpace"):
|
||||
relating_space = element
|
||||
relating_space_obj = obj
|
||||
else:
|
||||
related_building_element = element
|
||||
related_building_element_obj = obj
|
||||
elif len(objs) == 1:
|
||||
# Optionally the user may select just the space, and the building element shall be auto-detected
|
||||
|
||||
def msg(self, context):
|
||||
self.layout.label(text="NO ACTIVE STOREY")
|
||||
|
||||
element = tool.Ifc.get_entity(objs[0])
|
||||
if element.is_a("IfcSpace"):
|
||||
relating_space = element
|
||||
relating_space_obj = objs[0]
|
||||
|
||||
target = bpy.context.scene.cursor.location
|
||||
|
||||
collection = context.view_layer.active_layer_collection.collection
|
||||
collection_obj = bpy.data.objects.get(collection.name)
|
||||
if not collection_obj:
|
||||
bpy.context.window_manager.popup_menu(msg, title="Error", icon="ERROR")
|
||||
return
|
||||
spatial_element = tool.Ifc.get_entity(collection_obj)
|
||||
if not spatial_element:
|
||||
bpy.context.window_manager.popup_menu(msg, title="Error", icon="ERROR")
|
||||
return
|
||||
|
||||
for subelement in ifcopenshell.util.element.get_decomposition(spatial_element):
|
||||
if not (subelement.is_a("IfcWall") or subelement.is_a("IfcSlab")):
|
||||
continue
|
||||
obj = tool.Ifc.get_object(subelement)
|
||||
if obj:
|
||||
raycast = obj.closest_point_on_mesh(obj.matrix_world.inverted() @ target, distance=0.1)
|
||||
if raycast[0]:
|
||||
related_building_element = subelement
|
||||
related_building_element_obj = obj
|
||||
break
|
||||
|
||||
if not relating_space or not related_building_element:
|
||||
return
|
||||
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(relating_space_obj.data)
|
||||
bmesh.ops.dissolve_limit(bm, angle_limit=pi * 2 / 360, verts=bm.verts, edges=bm.edges)
|
||||
|
||||
target_distance = inf
|
||||
target_face = None
|
||||
for face in bm.faces:
|
||||
centroid = relating_space_obj.matrix_world @ face.calc_center_median()
|
||||
raycast = related_building_element_obj.closest_point_on_mesh(
|
||||
related_building_element_obj.matrix_world.inverted() @ centroid, distance=1
|
||||
)
|
||||
if raycast[0]:
|
||||
distance = (related_building_element_obj.matrix_world @ raycast[1] - centroid).length
|
||||
if distance < target_distance:
|
||||
target_face = face
|
||||
target_distance = distance
|
||||
|
||||
if not target_face:
|
||||
return
|
||||
|
||||
parent_boundary = tool.Ifc.run("root.create_entity", ifc_class=context.scene.BIMModelProperties.boundary_class)
|
||||
|
||||
# Is this right? Or should I use loop?
|
||||
target_face_verts = [v.co.copy() for v in target_face.verts]
|
||||
target_face_matrix = self.get_face_matrix(*[v.copy() for v in target_face_verts[0:3]])
|
||||
target_face_matrix_i = target_face_matrix.inverted()
|
||||
|
||||
target_face_polygon = shapely.Polygon([tuple((target_face_matrix_i @ v).xy) for v in target_face_verts])
|
||||
|
||||
related_building_element_polygon = self.get_flattened_polygon(
|
||||
related_building_element, relating_space_obj, target_face_matrix_i
|
||||
)
|
||||
|
||||
gross_boundary_polygon = target_face_polygon.intersection(related_building_element_polygon)
|
||||
|
||||
if type(gross_boundary_polygon) == shapely.GeometryCollection:
|
||||
for geom in gross_boundary_polygon.geoms:
|
||||
if type(geom) == shapely.Polygon:
|
||||
gross_boundary_polygon = geom
|
||||
break
|
||||
|
||||
# The gross boundary polygon may not be a true gross boundary since it
|
||||
# may have openings already removed, such as in IFC4 Reference View. So
|
||||
# we cheat by using the exterior boundary to mean "gross". Later, we
|
||||
# can use this to check whether or not the opening is relevant to our
|
||||
# space.
|
||||
exterior_boundary_polygon = shapely.Polygon(gross_boundary_polygon.exterior.coords)
|
||||
|
||||
net_boundary_polygon = shapely.Polygon(gross_boundary_polygon)
|
||||
|
||||
inner_boundaries = []
|
||||
|
||||
for rel in getattr(related_building_element, "HasOpenings", []):
|
||||
opening = rel.RelatedOpeningElement
|
||||
filling = None
|
||||
if opening.HasFillings:
|
||||
filling = opening.HasFillings[0].RelatedBuildingElement
|
||||
|
||||
opening_polygon = self.get_flattened_polygon(opening, relating_space_obj, target_face_matrix_i)
|
||||
|
||||
net_boundary_polygon = net_boundary_polygon.difference(opening_polygon)
|
||||
# Only openings that are projected onto our exterior boundary are relevant.
|
||||
if opening_polygon.intersection(exterior_boundary_polygon).area == 0:
|
||||
continue
|
||||
|
||||
connection_geometry = self.create_connection_geometry_from_polygon(opening_polygon, target_face_matrix)
|
||||
boundary = tool.Ifc.run("root.create_entity", ifc_class=context.scene.BIMModelProperties.boundary_class)
|
||||
boundary.RelatingSpace = relating_space
|
||||
boundary.RelatedBuildingElement = filling or related_building_element
|
||||
boundary.ConnectionGeometry = connection_geometry
|
||||
boundary.PhysicalOrVirtualBoundary = "PHYSICAL" if filling else "VIRTUAL"
|
||||
boundary.InternalOrExternalBoundary = "INTERNAL"
|
||||
|
||||
if boundary.is_a("IfcRelSpaceBoundary2ndLevel"):
|
||||
boundary.ParentBoundary = parent_boundary
|
||||
|
||||
connection_geometry = self.create_connection_geometry_from_polygon(net_boundary_polygon, target_face_matrix)
|
||||
parent_boundary.RelatingSpace = relating_space
|
||||
parent_boundary.RelatedBuildingElement = related_building_element
|
||||
parent_boundary.ConnectionGeometry = connection_geometry
|
||||
parent_boundary.PhysicalOrVirtualBoundary = "PHYSICAL"
|
||||
parent_boundary.InternalOrExternalBoundary = "INTERNAL"
|
||||
|
||||
bpy.ops.bim.show_boundaries()
|
||||
obj = tool.Ifc.get_object(parent_boundary)
|
||||
obj.select_set(True)
|
||||
|
||||
def get_face_matrix(self, p1, p2, p3):
|
||||
edge1 = p2 - p1
|
||||
edge2 = p3 - p1
|
||||
normal = edge1.cross(edge2)
|
||||
z_axis = normal.normalized()
|
||||
x_axis = p2 - p1
|
||||
x_axis.normalize()
|
||||
y_axis = z_axis.cross(x_axis)
|
||||
|
||||
mat = Matrix()
|
||||
mat.col[0][:3] = x_axis
|
||||
mat.col[1][:3] = y_axis
|
||||
mat.col[2][:3] = z_axis
|
||||
mat.col[3][:3] = p1
|
||||
|
||||
return mat
|
||||
|
||||
def get_flattened_polygon(self, element, relating_space_obj, target_face_matrix_i):
|
||||
obj = tool.Ifc.get_object(element)
|
||||
if obj and tool.Ifc.is_moved(obj):
|
||||
blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
|
||||
|
||||
space_matrix_i = relating_space_obj.matrix_world.inverted()
|
||||
|
||||
settings = ifcopenshell.geom.settings()
|
||||
if not element.is_a("IfcOpeningElement"):
|
||||
settings.set(settings.DISABLE_OPENING_SUBTRACTIONS, True)
|
||||
settings.set(settings.STRICT_TOLERANCE, True)
|
||||
# geometry = ifcopenshell.geom.create_shape(settings, body)
|
||||
shape = ifcopenshell.geom.create_shape(settings, element)
|
||||
m = shape.transformation.matrix.data
|
||||
mat = Matrix(([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1]))
|
||||
verts = [space_matrix_i @ mat @ Vector(v) for v in ifcopenshell.util.shape.get_vertices(shape.geometry)]
|
||||
faces = ifcopenshell.util.shape.get_faces(shape.geometry)
|
||||
polygons = []
|
||||
for face in faces:
|
||||
polygon = shapely.Polygon([tuple((target_face_matrix_i @ verts[vi]).xy) for vi in face])
|
||||
polygons.append(polygon)
|
||||
return shapely.ops.unary_union(polygons)
|
||||
|
||||
def create_connection_geometry_from_polygon(self, polygon, target_face_matrix):
|
||||
surface = self.export_surface(polygon, target_face_matrix)
|
||||
return tool.Ifc.get().createIfcConnectionSurfaceGeometry(surface)
|
||||
|
||||
def export_surface(self, polygon, target_face_matrix):
|
||||
x_axis = target_face_matrix.col[0][:3]
|
||||
z_axis = target_face_matrix.col[2][:3]
|
||||
p1 = target_face_matrix.col[3][:3]
|
||||
|
||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
tool.Model.unit_scale = self.unit_scale
|
||||
|
||||
surface = tool.Ifc.get().createIfcCurveBoundedPlane()
|
||||
surface.BasisSurface = tool.Ifc.get().createIfcPlane(tool.Ifc.get().createIfcAxis2Placement3D(
|
||||
tool.Ifc.get().createIfcCartesianPoint([o / self.unit_scale for o in p1]),
|
||||
tool.Ifc.get().createIfcDirection([float(o) for o in z_axis]),
|
||||
tool.Ifc.get().createIfcDirection([float(o) for o in x_axis]),
|
||||
))
|
||||
|
||||
if tool.Ifc.get().schema != "IFC2X3":
|
||||
points = [tool.Model.convert_si_to_unit(list(co)) for co in polygon.exterior.coords]
|
||||
point_list = tool.Ifc.get().createIfcCartesianPointList2D(points)
|
||||
outer_boundary = tool.Ifc.get().createIfcIndexedPolyCurve(point_list, None, False)
|
||||
|
||||
inner_boundaries = []
|
||||
for interior in polygon.interiors:
|
||||
points = [tool.Model.convert_si_to_unit(list(co)) for co in interior.coords]
|
||||
point_list = tool.Ifc.get().createIfcCartesianPointList2D(points)
|
||||
inner_boundaries.append(tool.Ifc.get().createIfcIndexedPolyCurve(point_list, None, False))
|
||||
else:
|
||||
pass # TODO
|
||||
|
||||
surface.OuterBoundary = outer_boundary
|
||||
surface.InnerBoundaries = inner_boundaries
|
||||
|
||||
return surface
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import bpy
|
||||
from bpy.types import PropertyGroup
|
||||
from blenderbim.bim.prop import ObjProperty
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
@@ -52,9 +53,13 @@ def element_filter(self, object):
|
||||
return False
|
||||
|
||||
|
||||
class BIMBoundaryProperties(PropertyGroup):
|
||||
class BIMObjectBoundaryProperties(PropertyGroup):
|
||||
is_editing: BoolProperty(name="Is Editing")
|
||||
relating_space: PointerProperty(name="RelatingSpace", type=bpy.types.Object, poll=space_filter)
|
||||
related_building_element: PointerProperty(name="RelatedBuildingElement", type=bpy.types.Object, poll=element_filter)
|
||||
parent_boundary: PointerProperty(name="ParentBoundary", type=bpy.types.Object, poll=boundary_filter)
|
||||
corresponding_boundary: PointerProperty(name="CorrespondingBoundary", type=bpy.types.Object, poll=boundary_filter)
|
||||
|
||||
|
||||
class BIMBoundaryProperties(PropertyGroup):
|
||||
boundaries: bpy.props.CollectionProperty(type=ObjProperty)
|
||||
|
||||
@@ -21,7 +21,7 @@ import blenderbim.bim.helper
|
||||
from bpy.types import Panel, UIList
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
import blenderbim.tool as tool
|
||||
from ifcopenshell.api.boundary.data import Data
|
||||
from blenderbim.bim.module.boundary.data import SpaceBoundariesData
|
||||
|
||||
|
||||
class BIM_PT_SceneBoundaries(Panel):
|
||||
@@ -67,7 +67,6 @@ class BIM_PT_Boundary(Panel):
|
||||
def draw(self, context):
|
||||
props = context.active_object.BIMObjectProperties
|
||||
ifc_file = tool.Ifc.get()
|
||||
element = ifc_file.by_id(props.ifc_definition_id)
|
||||
boundary = ifc_file.by_id(props.ifc_definition_id)
|
||||
self.bprops = context.active_object.bim_boundary_properties
|
||||
if self.bprops.is_editing:
|
||||
@@ -103,6 +102,11 @@ class BIM_PT_Boundary(Panel):
|
||||
row.label(text=f"{entity.is_a()}/{entity.Name}")
|
||||
op = row.operator("bim.select_global_id", text="", icon="OBJECT_DATA")
|
||||
op.global_id = entity.GlobalId
|
||||
if ifc_attribute in ("RelatingSpace", "RelatedBuildingElement"):
|
||||
op = row.operator("bim.select_related_element_boundaries", text="", icon="RESTRICT_SELECT_OFF")
|
||||
op.related_element = entity.id()
|
||||
op = row.operator("bim.select_related_element_type_boundaries", text="", icon="ASSET_MANAGER")
|
||||
op.related_element = entity.id()
|
||||
else:
|
||||
row.label(text="")
|
||||
|
||||
@@ -119,6 +123,7 @@ class BIM_PT_SpaceBoundaries(Panel):
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "object"
|
||||
bl_order = 1
|
||||
bl_parent_id = "BIM_PT_geometry_object"
|
||||
|
||||
@classmethod
|
||||
@@ -130,28 +135,23 @@ class BIM_PT_SpaceBoundaries(Panel):
|
||||
return False
|
||||
if not IfcStore.get_element(props.ifc_definition_id):
|
||||
return False
|
||||
valid_classes = ("IfcSpace", "IfcExternalSpatialElement")
|
||||
entity = IfcStore.get_file().by_id(props.ifc_definition_id)
|
||||
for ifc_class in valid_classes:
|
||||
if entity.is_a(ifc_class):
|
||||
element = tool.Ifc.get_entity(context.active_object)
|
||||
for ifc_class in ("IfcSpace", "IfcExternalSpatialElement"):
|
||||
if element.is_a(ifc_class):
|
||||
return True
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
if not SpaceBoundariesData.is_loaded:
|
||||
SpaceBoundariesData.load()
|
||||
|
||||
self.props = context.active_object.BIMObjectProperties
|
||||
self.ifc_file = tool.Ifc.get()
|
||||
row = self.layout.row()
|
||||
row.operator("bim.load_space_boundaries")
|
||||
if not Data.is_loaded:
|
||||
Data.load(self.ifc_file)
|
||||
for boundary_id in Data.spaces.get(self.props.ifc_definition_id, []):
|
||||
boundary_data = Data.boundaries[boundary_id]
|
||||
building_element = self.ifc_file.by_id(boundary_data["RelatedBuildingElement"])
|
||||
row.operator("bim.select_space_boundaries", text="", icon="RESTRICT_SELECT_OFF")
|
||||
for boundary in SpaceBoundariesData.data["boundaries"]:
|
||||
row = self.layout.row()
|
||||
if building_element:
|
||||
bld_el_description = f"{building_element.is_a()}/{building_element.Name}"
|
||||
else:
|
||||
bld_el_description = None
|
||||
row.label(text=f"{boundary_id} > {bld_el_description}", icon="GHOST_ENABLED")
|
||||
row.label(text=boundary["description"], icon="GHOST_ENABLED")
|
||||
op = row.operator("bim.load_boundary", text="", icon="RESTRICT_SELECT_OFF")
|
||||
op.boundary_id = boundary_id
|
||||
op.boundary_id = boundary["id"]
|
||||
|
||||
@@ -33,6 +33,10 @@ classes = (
|
||||
operator.RewindBrickClass,
|
||||
operator.ViewBrickClass,
|
||||
operator.ViewBrickItem,
|
||||
operator.UndoBrick,
|
||||
operator.RedoBrick,
|
||||
operator.SerializeBrick,
|
||||
operator.AddBrickNamespace,
|
||||
prop.Brick,
|
||||
prop.BIMBrickProperties,
|
||||
ui.BIM_PT_brickschema,
|
||||
|
||||
@@ -109,8 +109,10 @@ class BrickschemaData:
|
||||
if BrickStore.graph is None:
|
||||
return []
|
||||
results = []
|
||||
filter = ["brick", "owl", "w3", "xml"]
|
||||
for alias, uri in BrickStore.graph.namespaces():
|
||||
results.append((uri, f"{alias}: {uri}", ""))
|
||||
if alias not in filter:
|
||||
results.append((uri, f"{alias}: {uri}", ""))
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -22,7 +22,7 @@ import blenderbim.tool as tool
|
||||
import blenderbim.core.brick as core
|
||||
import blenderbim.bim.handler
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
from blenderbim.tool.brick import BrickStore
|
||||
|
||||
class Operator:
|
||||
def execute(self, context):
|
||||
@@ -126,6 +126,7 @@ class AddBrick(bpy.types.Operator, Operator):
|
||||
namespace=props.namespace,
|
||||
brick_class=props.brick_equipment_class,
|
||||
library=library,
|
||||
label=props.new_brick_label
|
||||
)
|
||||
|
||||
|
||||
@@ -189,3 +190,54 @@ class RemoveBrick(bpy.types.Operator, Operator):
|
||||
library=tool.Ifc.get().by_id(int(props.libraries)) if props.libraries else None,
|
||||
brick_uri=props.bricks[props.active_brick_index].uri,
|
||||
)
|
||||
|
||||
class UndoBrick(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.undo_brick"
|
||||
bl_label = "Undo Brick"
|
||||
|
||||
def _execute(self, context):
|
||||
core.undo_brick(tool.Brick)
|
||||
|
||||
class RedoBrick(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.redo_brick"
|
||||
bl_label = "Redo Brick"
|
||||
|
||||
def _execute(self, context):
|
||||
core.redo_brick(tool.Brick)
|
||||
|
||||
class SerializeBrick(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.serialize_brick"
|
||||
bl_label = "Serialize Brick"
|
||||
filter_glob: bpy.props.StringProperty(default="*.ttl", options={"HIDDEN"})
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
should_save_as: bpy.props.BoolProperty(name="Should Save As", default=False, options={"HIDDEN"})
|
||||
|
||||
def invoke(self, context, event):
|
||||
if self.should_save_as or not BrickStore.path:
|
||||
WindowManager = context.window_manager
|
||||
WindowManager.fileselect_add(self)
|
||||
return {"RUNNING_MODAL"}
|
||||
else:
|
||||
return self.execute(context)
|
||||
|
||||
def _execute(self, context):
|
||||
if self.should_save_as or not BrickStore.path:
|
||||
BrickStore.path = self.filepath
|
||||
core.serialize_brick(tool.Brick)
|
||||
return {"FINISHED"}
|
||||
|
||||
@classmethod
|
||||
def description(cls, context, properties):
|
||||
if properties.should_save_as:
|
||||
return "Save Brick project to a selected file"
|
||||
return "Save the Brick project"
|
||||
|
||||
class AddBrickNamespace(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.add_brick_namespace"
|
||||
bl_label = "Add Brick Namespace"
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMBrickProperties
|
||||
alias = props.new_brick_namespace_alias
|
||||
uri = props.new_brick_namespace_uri
|
||||
core.add_namespace(tool.Brick, alias=alias, uri=uri)
|
||||
@@ -69,3 +69,7 @@ class BIMBrickProperties(PropertyGroup):
|
||||
libraries: EnumProperty(name="Libraries", items=get_libraries)
|
||||
namespace: EnumProperty(name="Namespace", items=get_namespaces)
|
||||
brick_equipment_class: EnumProperty(name="Brick Equipment Class", items=get_brick_equipment_classes)
|
||||
brick_settings_toggled: BoolProperty(name="Brick Settings Toggled", default=False)
|
||||
new_brick_label: StringProperty(name="New Brick Label")
|
||||
new_brick_namespace_alias: StringProperty(name="New Brick Namespace Alias")
|
||||
new_brick_namespace_uri: StringProperty(name="New Brick Namespace URI")
|
||||
@@ -20,7 +20,7 @@ import blenderbim.tool as tool
|
||||
from bpy.types import Panel, UIList
|
||||
from blenderbim.bim.helper import prop_with_search
|
||||
from blenderbim.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
|
||||
|
||||
from blenderbim.tool.brick import BrickStore
|
||||
|
||||
class BIM_PT_brickschema(Panel):
|
||||
bl_label = "Brickschema Project"
|
||||
@@ -41,15 +41,39 @@ class BIM_PT_brickschema(Panel):
|
||||
row.operator("bim.load_brick_project", text="Load Project")
|
||||
return
|
||||
|
||||
if BrickStore.path:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=BrickStore.path, icon='FILEBROWSER')
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
if len(self.props.brick_breadcrumbs):
|
||||
row.operator("bim.rewind_brick_class", text="", icon="FRAME_PREV")
|
||||
row.label(text=self.props.active_brick_class)
|
||||
row.prop(data=self.props, property="brick_settings_toggled", text="", icon="PREFERENCES")
|
||||
row.operator("bim.refresh_brick_viewer", text="", icon="FILE_REFRESH")
|
||||
row.operator("bim.close_brick_project", text="", icon="CANCEL")
|
||||
|
||||
if self.props.brick_settings_toggled:
|
||||
box = self.layout.box()
|
||||
row = box.row(align=True)
|
||||
row.label(text="Active Namespace:")
|
||||
row = box.row(align=True)
|
||||
prop_with_search(row, self.props, "namespace", text="")
|
||||
row = box.row(align=True)
|
||||
row.label(text="Bind New Namespace:")
|
||||
row = box.row(align=True)
|
||||
row.prop(data=self.props, property="new_brick_namespace_alias", text="")
|
||||
col = row.column()
|
||||
col.alignment = "CENTER"
|
||||
col.scale_x = 1.1
|
||||
col.label(text=":")
|
||||
row.prop(data=self.props, property="new_brick_namespace_uri", text="")
|
||||
row.operator("bim.add_brick_namespace", text="", icon="ADD")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
prop_with_search(row, self.props, "namespace", text="")
|
||||
row.label(text="Create Entity:")
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(data=self.props, property="new_brick_label", text="")
|
||||
prop_with_search(row, self.props, "brick_equipment_class", text="")
|
||||
row.operator("bim.add_brick", text="", icon="ADD")
|
||||
|
||||
@@ -58,6 +82,16 @@ class BIM_PT_brickschema(Panel):
|
||||
row.operator("bim.add_brick_feed", text="", icon="PLUGIN")
|
||||
row.operator("bim.remove_brick", text="", icon="X")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.undo_brick", icon="LOOP_BACK")
|
||||
row.operator("bim.redo_brick", icon="LOOP_FORWARDS")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
op = row.operator("bim.serialize_brick", icon="EXPORT", text="Save")
|
||||
op.should_save_as = False
|
||||
op = row.operator("bim.serialize_brick", icon="FILE_TICK", text="Save As")
|
||||
op.should_save_as = True
|
||||
|
||||
self.layout.template_list("BIM_UL_bricks", "", self.props, "bricks", self.props, "active_brick_index")
|
||||
|
||||
for attribute in BrickschemaData.data["attributes"]:
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
import bpy
|
||||
from blenderbim.bim.module.model.data import AuthoringData
|
||||
from blenderbim.bim.module.model.root import ConstrTypeEntityNotFound
|
||||
from bpy.types import PropertyGroup
|
||||
from math import pi
|
||||
|
||||
|
||||
class BIMCadProperties(PropertyGroup):
|
||||
@@ -28,3 +28,7 @@ class BIMCadProperties(PropertyGroup):
|
||||
distance: bpy.props.FloatProperty(name="Distance", default=0.1)
|
||||
x: bpy.props.FloatProperty(name="X", default=0.2)
|
||||
y: bpy.props.FloatProperty(name="Y", default=0.1)
|
||||
gable_roof_edge_angle: bpy.props.FloatProperty(
|
||||
name="Gable Roof Edge Angle", default=pi / 2, soft_min=0, soft_max=pi / 2, subtype="ANGLE"
|
||||
)
|
||||
gable_roof_separate_verts: bpy.props.BoolProperty(name="Separate Verts", default=True)
|
||||
|
||||
@@ -21,7 +21,7 @@ import bpy
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.bim.module.type.prop as type_prop
|
||||
from bpy.types import WorkSpaceTool
|
||||
from blenderbim.bim.module.model.data import AuthoringData
|
||||
from blenderbim.bim.module.model.data import AuthoringData, RailingData, RoofData
|
||||
|
||||
|
||||
class CadTool(WorkSpaceTool):
|
||||
@@ -33,8 +33,7 @@ class CadTool(WorkSpaceTool):
|
||||
bl_description = "Gives you CAD authoring related superpowers"
|
||||
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.cad")
|
||||
bl_widget = None
|
||||
# https://docs.blender.org/api/current/bpy.types.KeyMapItems.html
|
||||
bl_keymap = (
|
||||
bl_keymap = tool.Blender.get_default_selection_keypmap() + (
|
||||
("bim.cad_hotkey", {"type": "C", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_C")]}),
|
||||
("bim.cad_hotkey", {"type": "E", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_E")]}),
|
||||
("bim.cad_hotkey", {"type": "F", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_F")]}),
|
||||
@@ -46,20 +45,27 @@ class CadTool(WorkSpaceTool):
|
||||
("bim.cad_hotkey", {"type": "X", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_X")]}),
|
||||
)
|
||||
|
||||
def draw_settings(context, layout, tool):
|
||||
def draw_settings(context, layout, workspace_tool):
|
||||
obj = context.active_object
|
||||
if obj and obj.data and hasattr(obj.data, "BIMMeshProperties") and obj.data.BIMMeshProperties.is_profile:
|
||||
if not obj or not obj.data:
|
||||
return
|
||||
if hasattr(obj.data, "BIMMeshProperties") and obj.data.BIMMeshProperties.subshape_type == "PROFILE":
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_Q")
|
||||
if obj.BIMObjectProperties.ifc_definition_id:
|
||||
row.operator("bim.edit_extrusion_profile", text="Save Profile")
|
||||
row.operator("bim.align_view_to_profile", text="", icon="AXIS_FRONT")
|
||||
row.operator("bim.disable_editing_extrusion_profile", text="", icon="CANCEL")
|
||||
else:
|
||||
row.operator("bim.edit_arbitrary_profile", text="Save Profile")
|
||||
row.operator("bim.align_view_to_profile", text="", icon="AXIS_FRONT")
|
||||
row.operator("bim.disable_editing_arbitrary_profile", text="", icon="CANCEL")
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if element:
|
||||
if element.is_a("IfcProfileDef"):
|
||||
row.operator("bim.edit_arbitrary_profile", text="Save Profile")
|
||||
row.operator("bim.align_view_to_profile", text="", icon="AXIS_FRONT")
|
||||
row.operator("bim.disable_editing_arbitrary_profile", text="", icon="CANCEL")
|
||||
elif element.is_a("IfcRelSpaceBoundary"):
|
||||
row.operator("bim.edit_boundary_geometry", text="Save Profile")
|
||||
row.operator("bim.disable_editing_boundary_geometry", text="", icon="CANCEL")
|
||||
else:
|
||||
row.operator("bim.edit_extrusion_profile", text="Save Profile")
|
||||
row.operator("bim.align_view_to_profile", text="", icon="AXIS_FRONT")
|
||||
row.operator("bim.disable_editing_extrusion_profile", text="", icon="CANCEL")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
@@ -100,7 +106,60 @@ class CadTool(WorkSpaceTool):
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_X")
|
||||
row.operator("bim.reset_vertex", text="Reset Vertex")
|
||||
|
||||
elif hasattr(obj.data, "BIMMeshProperties") and obj.data.BIMMeshProperties.subshape_type == "AXIS":
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_Q")
|
||||
row.operator("bim.edit_extrusion_axis", text="Save Axis")
|
||||
row.operator("bim.disable_editing_extrusion_axis", text="", icon="CANCEL")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_E")
|
||||
row.operator("bim.cad_hotkey", text="Extend").hotkey = "S_E"
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_T")
|
||||
row.operator("bim.cad_hotkey", text="Mitre").hotkey = "S_T"
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_F")
|
||||
row.operator("bim.cad_hotkey", text="Fillet").hotkey = "S_F"
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_O")
|
||||
row.operator("bim.cad_hotkey", text="Offset").hotkey = "S_O"
|
||||
|
||||
else:
|
||||
if (
|
||||
(RailingData.is_loaded or not RailingData.load())
|
||||
and RailingData.data["parameters"]
|
||||
and context.active_object.BIMRailingProperties.is_editing_path
|
||||
):
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon=f"EVENT_TAB")
|
||||
row.operator("bim.finish_editing_railing_path")
|
||||
row.operator("bim.cancel_editing_railing_path", icon="CANCEL", text="")
|
||||
|
||||
elif (
|
||||
(RoofData.is_loaded or not RoofData.load())
|
||||
and RoofData.data["parameters"]
|
||||
and context.active_object.BIMRoofProperties.is_editing_path
|
||||
):
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon=f"EVENT_TAB")
|
||||
row.operator("bim.finish_editing_roof_path")
|
||||
row.operator("bim.cancel_editing_roof_path", icon="CANCEL", text="")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_R")
|
||||
row.operator("bim.cad_hotkey", text="Set Gable Roof Angle").hotkey = "S_R"
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_E")
|
||||
@@ -148,20 +207,32 @@ class CadHotkey(bpy.types.Operator):
|
||||
if self.is_profile():
|
||||
row = self.layout.row()
|
||||
row.prop(props, "radius")
|
||||
|
||||
elif self.hotkey == "S_F":
|
||||
if not self.is_profile():
|
||||
row = self.layout.row()
|
||||
row.prop(props, "resolution")
|
||||
row = self.layout.row()
|
||||
row.prop(props, "radius")
|
||||
|
||||
elif self.hotkey == "S_O":
|
||||
row = self.layout.row()
|
||||
row.prop(props, "distance")
|
||||
|
||||
elif self.hotkey == "S_R":
|
||||
row = self.layout.row()
|
||||
row.prop(props, "x")
|
||||
row = self.layout.row()
|
||||
row.prop(props, "y")
|
||||
if self.is_profile():
|
||||
row = self.layout.row()
|
||||
row.prop(props, "x")
|
||||
row = self.layout.row()
|
||||
row.prop(props, "y")
|
||||
elif (
|
||||
(RoofData.is_loaded or not RoofData.load())
|
||||
and RoofData.data["parameters"]
|
||||
and bpy.context.active_object.BIMRoofProperties.is_editing_path
|
||||
):
|
||||
self.layout.row().prop(props, "gable_roof_edge_angle")
|
||||
self.layout.row().prop(props, "gable_roof_separate_verts")
|
||||
|
||||
elif self.hotkey == "S_V":
|
||||
if not self.is_profile():
|
||||
row = self.layout.row()
|
||||
@@ -186,14 +257,28 @@ class CadHotkey(bpy.types.Operator):
|
||||
bpy.ops.bim.cad_offset(distance=self.props.distance)
|
||||
|
||||
def hotkey_S_Q(self):
|
||||
if tool.Ifc.get_entity(bpy.context.active_object):
|
||||
bpy.ops.bim.edit_extrusion_profile()
|
||||
else:
|
||||
bpy.ops.bim.edit_arbitrary_profile()
|
||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
if bpy.context.active_object.data.BIMMeshProperties.subshape_type == "PROFILE":
|
||||
if element.is_a("IfcProfileDef"):
|
||||
bpy.ops.bim.edit_arbitrary_profile()
|
||||
elif element.is_a("IfcRelSpaceBoundary"):
|
||||
bpy.ops.bim.edit_boundary_geometry()
|
||||
else:
|
||||
bpy.ops.bim.edit_extrusion_profile()
|
||||
elif bpy.context.active_object.data.BIMMeshProperties.subshape_type == "AXIS":
|
||||
bpy.ops.bim.edit_extrusion_axis()
|
||||
|
||||
def hotkey_S_R(self):
|
||||
if self.is_profile():
|
||||
bpy.ops.bim.add_rectangle(x=self.props.x, y=self.props.y)
|
||||
elif (
|
||||
(RoofData.is_loaded or not RoofData.load())
|
||||
and RoofData.data["parameters"]
|
||||
and bpy.context.active_object.BIMRoofProperties.is_editing_path
|
||||
):
|
||||
bpy.ops.bim.set_gable_roof_edge_angle(
|
||||
angle=self.props.gable_roof_edge_angle, separate_verts=self.props.gable_roof_separate_verts
|
||||
)
|
||||
|
||||
def hotkey_S_T(self):
|
||||
bpy.ops.bim.cad_mitre()
|
||||
@@ -210,4 +295,9 @@ class CadHotkey(bpy.types.Operator):
|
||||
|
||||
def is_profile(self):
|
||||
obj = bpy.context.active_object
|
||||
return obj and obj.data and hasattr(obj.data, "BIMMeshProperties") and obj.data.BIMMeshProperties.is_profile
|
||||
return (
|
||||
obj
|
||||
and obj.data
|
||||
and hasattr(obj.data, "BIMMeshProperties")
|
||||
and obj.data.BIMMeshProperties.subshape_type == "PROFILE"
|
||||
)
|
||||
|
||||
@@ -22,7 +22,8 @@ import json
|
||||
import bmesh
|
||||
import logging
|
||||
import numpy as np
|
||||
from mathutils import Matrix
|
||||
import ifcopenshell
|
||||
from mathutils import Matrix, Vector
|
||||
from math import radians
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
@@ -30,8 +31,10 @@ from blenderbim.bim.ifc import IfcStore
|
||||
class ExportClashSets(bpy.types.Operator):
|
||||
bl_idname = "bim.export_clash_sets"
|
||||
bl_label = "Export Clash Sets"
|
||||
bl_description = "Export clash sets to a selected file"
|
||||
filename_ext = ".json"
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
filter_glob: bpy.props.StringProperty(default="*.json", options={"HIDDEN"})
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".json")
|
||||
@@ -62,8 +65,10 @@ class ImportClashSets(bpy.types.Operator):
|
||||
bl_idname = "bim.import_clash_sets"
|
||||
bl_label = "Import Clash Sets"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Import clash sets from a selected file"
|
||||
filename_ext = ".json"
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
filter_glob: bpy.props.StringProperty(default="*.json", options={"HIDDEN"})
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".json")
|
||||
@@ -98,6 +103,7 @@ class AddClashSet(bpy.types.Operator):
|
||||
bl_idname = "bim.add_clash_set"
|
||||
bl_label = "Add Clash Set"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Add a clash set"
|
||||
|
||||
def execute(self, context):
|
||||
new = context.scene.BIMClashProperties.clash_sets.add()
|
||||
@@ -110,6 +116,7 @@ class RemoveClashSet(bpy.types.Operator):
|
||||
bl_idname = "bim.remove_clash_set"
|
||||
bl_label = "Remove Clash Set"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Remove the selected clash set"
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
@@ -121,6 +128,7 @@ class AddClashSource(bpy.types.Operator):
|
||||
bl_idname = "bim.add_clash_source"
|
||||
bl_label = "Add Clash Source"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Add a clash source to this group"
|
||||
group: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
@@ -133,6 +141,7 @@ class RemoveClashSource(bpy.types.Operator):
|
||||
bl_idname = "bim.remove_clash_source"
|
||||
bl_label = "Remove Clash Source"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Remove this clash source"
|
||||
index: bpy.props.IntProperty()
|
||||
group: bpy.props.StringProperty()
|
||||
|
||||
@@ -146,6 +155,7 @@ class SelectClashSource(bpy.types.Operator):
|
||||
bl_idname = "bim.select_clash_source"
|
||||
bl_label = "Select Clash Source"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Select an IFC file to add as a clash source"
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
filter_glob: bpy.props.StringProperty(default="*.ifc", options={"HIDDEN"})
|
||||
index: bpy.props.IntProperty()
|
||||
@@ -194,11 +204,13 @@ class SelectSmartGroupedClashesPath(bpy.types.Operator):
|
||||
class ExecuteIfcClash(bpy.types.Operator):
|
||||
bl_idname = "bim.execute_ifc_clash"
|
||||
bl_label = "Execute IFC Clash"
|
||||
filename_ext = ".bcf"
|
||||
bl_description = "Execute clash detection and save the information to a .bcf or .json file"
|
||||
filter_glob: bpy.props.StringProperty(default="*.bcf;*.json", options={"HIDDEN"})
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
|
||||
def invoke(self, context, event):
|
||||
if ".json" not in bpy.data.filepath:
|
||||
_, extension = os.path.splitext(self.filepath)
|
||||
if extension != ".json":
|
||||
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".bcf")
|
||||
WindowManager = context.window_manager
|
||||
WindowManager.fileselect_add(self)
|
||||
@@ -207,9 +219,11 @@ class ExecuteIfcClash(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
from ifcclash import ifcclash
|
||||
|
||||
settings = ifcclash.ClashSettings()
|
||||
if ".json" not in self.filepath:
|
||||
_, extension = os.path.splitext(self.filepath)
|
||||
if extension != ".json":
|
||||
self.filepath = bpy.path.ensure_ext(self.filepath, ".bcf")
|
||||
|
||||
settings = ifcclash.ClashSettings()
|
||||
settings.output = self.filepath
|
||||
settings.logger = logging.getLogger("Clash")
|
||||
settings.logger.setLevel(logging.DEBUG)
|
||||
@@ -217,12 +231,28 @@ class ExecuteIfcClash(bpy.types.Operator):
|
||||
|
||||
if context.scene.BIMClashProperties.should_create_clash_snapshots:
|
||||
|
||||
def get_viewpoint_snapshot(viewpoint, mat):
|
||||
def get_viewpoint_snapshot(viewpoint):
|
||||
camera = bpy.data.objects.get("IFC Clash Camera")
|
||||
if not camera:
|
||||
camera = bpy.data.objects.new("IFC Clash Camera", bpy.data.cameras.new("IFC Clash Camera"))
|
||||
context.scene.collection.objects.link(camera)
|
||||
camera.matrix_world = Matrix(mat)
|
||||
|
||||
bcf_camera = viewpoint.visualization_info.perspective_camera
|
||||
p = bcf_camera.camera_view_point
|
||||
z = bcf_camera.camera_direction
|
||||
z = Vector([z.x, z.y, z.z]) * -1
|
||||
y = bcf_camera.camera_up_vector
|
||||
y = Vector([y.x, y.y, y.z])
|
||||
x = y.cross(z)
|
||||
|
||||
mat = Matrix([
|
||||
[x[0], y[0], z[0], p.x],
|
||||
[x[1], y[1], z[1], p.y],
|
||||
[x[2], y[2], z[2], p.z],
|
||||
[0, 0, 0, 0],
|
||||
])
|
||||
|
||||
camera.matrix_world = mat
|
||||
context.scene.camera = camera
|
||||
camera.data.angle = radians(60)
|
||||
area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
|
||||
@@ -233,7 +263,8 @@ class ExecuteIfcClash(bpy.types.Operator):
|
||||
context.scene.render.image_settings.file_format = "PNG"
|
||||
context.scene.render.filepath = os.path.join(context.scene.BIMProperties.data_dir, "snapshot.png")
|
||||
bpy.ops.render.opengl(write_still=True)
|
||||
return context.scene.render.filepath
|
||||
with open(context.scene.render.filepath, "rb") as f:
|
||||
return ("snapshot.png", f.read())
|
||||
|
||||
clasher.get_viewpoint_snapshot = get_viewpoint_snapshot
|
||||
|
||||
@@ -261,6 +292,7 @@ class SelectIfcClashResults(bpy.types.Operator):
|
||||
bl_idname = "bim.select_ifc_clash_results"
|
||||
bl_label = "Select IFC Clash Results"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Select the clashing IFC geometry stored in a file"
|
||||
filename_ext = ".json"
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
|
||||
@@ -271,6 +303,7 @@ class SelectIfcClashResults(bpy.types.Operator):
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
self.filepath = bpy.path.ensure_ext(self.filepath, ".json")
|
||||
with open(self.filepath) as f:
|
||||
clash_sets = json.load(f)
|
||||
@@ -284,10 +317,26 @@ class SelectIfcClashResults(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
for clash in clash_set["clashes"].values():
|
||||
global_ids.extend([clash["a_global_id"], clash["b_global_id"]])
|
||||
|
||||
for obj in context.visible_objects:
|
||||
if not obj.BIMObjectProperties.ifc_definition_id:
|
||||
continue
|
||||
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
|
||||
ifc_file = ""
|
||||
for scene in obj.users_scene:
|
||||
if scene.BIMProperties.ifc_file:
|
||||
ifc_file = scene.BIMProperties.ifc_file
|
||||
if scene.library:
|
||||
break
|
||||
|
||||
if ifc_file:
|
||||
if ifc_file not in IfcStore.session_files:
|
||||
IfcStore.session_files[ifc_file] = ifcopenshell.open(ifc_file)
|
||||
element_file = IfcStore.session_files[ifc_file]
|
||||
else:
|
||||
element_file = self.file
|
||||
|
||||
element = element_file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
if element.GlobalId in global_ids:
|
||||
obj.select_set(True)
|
||||
return {"FINISHED"}
|
||||
@@ -304,14 +353,14 @@ class SmartClashGroup(bpy.types.Operator):
|
||||
return context.scene.BIMClashProperties.clash_results_path
|
||||
|
||||
def execute(self, context):
|
||||
import ifcclash
|
||||
from ifcclash import ifcclash
|
||||
|
||||
settings = ifcclash.IfcClashSettings()
|
||||
settings = ifcclash.ClashSettings()
|
||||
self.filepath = bpy.path.ensure_ext(context.scene.BIMClashProperties.clash_results_path, ".json")
|
||||
settings.output = self.filepath
|
||||
settings.logger = logging.getLogger("Clash")
|
||||
settings.logger.setLevel(logging.DEBUG)
|
||||
ifc_clasher = ifcclash.IfcClasher(settings)
|
||||
ifc_clasher = ifcclash.Clasher(settings)
|
||||
|
||||
with open(self.filepath) as f:
|
||||
clash_sets = json.load(f)
|
||||
|
||||
@@ -65,12 +65,13 @@ class ClassificationsData:
|
||||
|
||||
class ReferencesData:
|
||||
@classmethod
|
||||
def is_available_classification_added(cls):
|
||||
def active_classification_library(cls):
|
||||
if not IfcStore.classification_file or not IfcStore.classification_file.by_type("IfcClassification"):
|
||||
return False
|
||||
props = bpy.context.scene.BIMClassificationProperties
|
||||
name = IfcStore.classification_file.by_id(int(props.available_classifications)).Name
|
||||
return name in [e.Name for e in tool.Ifc.get().by_type("IfcClassification")]
|
||||
if name in [e.Name for e in tool.Ifc.get().by_type("IfcClassification")]:
|
||||
return name
|
||||
|
||||
|
||||
class ClassificationReferencesData(ReferencesData):
|
||||
@@ -81,7 +82,7 @@ class ClassificationReferencesData(ReferencesData):
|
||||
def load(cls):
|
||||
cls.is_loaded = True
|
||||
cls.data["references"] = cls.references()
|
||||
cls.data["is_available_classification_added"] = cls.is_available_classification_added()
|
||||
cls.data["active_classification_library"] = cls.active_classification_library()
|
||||
|
||||
@classmethod
|
||||
def references(cls):
|
||||
@@ -103,7 +104,7 @@ class MaterialClassificationsData(ReferencesData):
|
||||
def load(cls):
|
||||
cls.is_loaded = True
|
||||
cls.data["references"] = cls.references()
|
||||
cls.data["is_available_classification_added"] = cls.is_available_classification_added()
|
||||
cls.data["active_classification_library"] = cls.active_classification_library()
|
||||
|
||||
@classmethod
|
||||
def references(cls):
|
||||
@@ -125,7 +126,7 @@ class CostClassificationsData(ReferencesData):
|
||||
def load(cls):
|
||||
cls.is_loaded = True
|
||||
cls.data["references"] = cls.references()
|
||||
cls.data["is_available_classification_added"] = cls.is_available_classification_added()
|
||||
cls.data["active_classification_library"] = cls.active_classification_library()
|
||||
|
||||
@classmethod
|
||||
def references(cls):
|
||||
|
||||
@@ -100,12 +100,16 @@ class ReferenceUI:
|
||||
self.draw_reference_ui(reference)
|
||||
|
||||
def draw_add_ui(self, context):
|
||||
if not self.data.data["is_available_classification_added"]:
|
||||
if not self.data.data["active_classification_library"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="No Active Classification Library")
|
||||
row.operator("bim.load_classification_library", text="", icon="IMPORT")
|
||||
return
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.sprops, "available_classifications", text="")
|
||||
row.label(text=f"Active Classification Library: {self.data.data['active_classification_library']}")
|
||||
#row.prop(self.sprops, "available_classifications", text="")
|
||||
if not self.sprops.available_library_references:
|
||||
op = row.operator("bim.change_classification_level", text="", icon="IMPORT")
|
||||
op = row.operator("bim.change_classification_level", text="", icon="GREASEPENCIL")
|
||||
op.parent_id = int(self.sprops.available_classifications)
|
||||
return
|
||||
if self.sprops.active_library_referenced_source:
|
||||
|
||||