diff --git a/Cargo.lock b/Cargo.lock index a0fa4571a992c3cd325a54e15a7889d11bf97b58..a3cfd778b0a943b1f7078235249c6d5a45d08aff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -207,9 +207,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -222,43 +222,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" [[package]] name = "approx" @@ -283,7 +283,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -421,9 +421,9 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" dependencies = [ "arrayvec", ] @@ -571,7 +571,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -655,7 +655,7 @@ checksum = "3fbfc33a4c6b80760bb8bf850a2cc65a1e031da62fd3ca8b552189104dc98514" dependencies = [ "bevy_macro_utils", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -704,7 +704,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -773,7 +773,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -900,7 +900,7 @@ checksum = "bfc65e570012e64a21f3546df68591aaede8349e6174fb500071677f54f06630" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", "toml_edit", ] @@ -989,7 +989,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", "uuid", ] @@ -1025,7 +1025,7 @@ dependencies = [ "encase", "futures-lite", "hexasphere", - "image 0.25.2", + "image 0.25.4", "js-sys", "ktx2", "naga", @@ -1050,7 +1050,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1122,7 +1122,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1242,7 +1242,7 @@ checksum = "38f1ab8f2f6f58439d260081d89a42b02690e5fdd64f814edc9417d33fcf2857" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1304,7 +1304,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1392,9 +1392,9 @@ dependencies = [ [[package]] name = "built" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" [[package]] name = "bumpalo" @@ -1404,9 +1404,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" dependencies = [ "bytemuck_derive", ] @@ -1419,7 +1419,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1436,9 +1436,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "calloop" @@ -1456,9 +1456,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.28" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc", @@ -1551,9 +1551,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -1561,9 +1561,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -1580,7 +1580,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1616,9 +1616,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colorous" @@ -1959,7 +1959,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1981,7 +1981,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2025,11 +2025,11 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" dependencies = [ - "derive_builder_macro 0.20.1", + "derive_builder_macro 0.20.2", ] [[package]] @@ -2046,14 +2046,14 @@ dependencies = [ [[package]] name = "derive_builder_core" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2068,12 +2068,12 @@ dependencies = [ [[package]] name = "derive_builder_macro" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ - "derive_builder_core 0.20.1", - "syn 2.0.79", + "derive_builder_core 0.20.2", + "syn 2.0.85", ] [[package]] @@ -2159,9 +2159,9 @@ dependencies = [ [[package]] name = "dwrote" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da3498378ed373237bdef1eddcc64e7be2d3ba4841f4c22a998e81cadeea83c" +checksum = "70182709525a3632b2ba96b6569225467b18ecb4a77f46d255f713a6bebf05fd" dependencies = [ "lazy_static", "libc", @@ -2216,7 +2216,7 @@ checksum = "fd31dbbd9743684d339f907a87fe212cb7b51d75b9e8e74181fe363199ee9b47" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2334,9 +2334,9 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fdeflate" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" dependencies = [ "simd-adler32", ] @@ -2371,9 +2371,9 @@ checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d" [[package]] name = "flume" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "spin", ] @@ -2427,7 +2427,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2644,7 +2644,7 @@ dependencies = [ "inflections", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2893,9 +2893,9 @@ dependencies = [ [[package]] name = "image" -version = "0.25.2" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" +checksum = "bc144d44a31d753b02ce64093d532f55ff8dc4ebf2ffb8a63c0dda691385acae" dependencies = [ "bytemuck", "byteorder-lite", @@ -2916,9 +2916,9 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" +checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" dependencies = [ "byteorder-lite", "quick-error", @@ -2926,15 +2926,15 @@ dependencies = [ [[package]] name = "imgref" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" [[package]] name = "immutable-chunkmap" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4419f022e55cc63d5bbd6b44b71e1d226b9c9480a47824c706e9d54e5c40c5eb" +checksum = "12f97096f508d54f8f8ab8957862eee2ccd628847b6217af1a335e1c44dee578" dependencies = [ "arrayvec", ] @@ -2993,7 +2993,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -3075,9 +3075,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -3142,9 +3142,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libflate" @@ -3209,17 +3209,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "libredox" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" -dependencies = [ - "bitflags 2.6.0", - "libc", - "redox_syscall 0.4.1", -] - [[package]] name = "libredox" version = "0.1.3" @@ -3228,6 +3217,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", + "redox_syscall 0.5.7", ] [[package]] @@ -3434,9 +3424,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.33.0" +version = "0.33.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c4b5f057b303842cf3262c27e465f4c303572e7f6b0648f60e16248ac3397f4" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" dependencies = [ "approx", "matrixmultiply", @@ -3457,7 +3447,7 @@ checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -3621,7 +3611,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -3683,7 +3673,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -3963,13 +3953,13 @@ dependencies = [ "bevy", "bevy_flycam", "chrono", - "clap 4.5.19", + "clap 4.5.20", "colorous", "csv", "delaunator", "embed-doc-image", "env_logger", - "image 0.25.2", + "image 0.25.4", "itertools 0.13.0", "kahan", "log", @@ -4006,11 +3996,11 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.47" +version = "0.3.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" +checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" dependencies = [ - "libredox 0.0.2", + "libredox", ] [[package]] @@ -4127,29 +4117,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "piper" @@ -4283,30 +4273,30 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -4412,9 +4402,9 @@ dependencies = [ [[package]] name = "ravif" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f0bfd976333248de2078d350bfdf182ff96e168a24d23d2436cef320dd4bdd" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" dependencies = [ "avif-serialize", "imgref", @@ -4487,15 +4477,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", - "libredox 0.1.3", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -4546,9 +4536,6 @@ name = "rgb" version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" -dependencies = [ - "bytemuck", -] [[package]] name = "rle-decode-fast" @@ -4640,9 +4627,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags 2.6.0", "errno", @@ -4653,9 +4640,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ruzstd" @@ -4710,29 +4697,29 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -4931,7 +4918,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -4953,9 +4940,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -5047,22 +5034,22 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -5197,7 +5184,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -5376,9 +5363,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", "rand", @@ -5421,7 +5408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349ed9e45296a581f455bc18039878f409992999bc1d5da12a6800eb18c8752f" dependencies = [ "anyhow", - "derive_builder 0.20.1", + "derive_builder 0.20.2", "rustversion", "vergen-lib", ] @@ -5433,7 +5420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e771aff771c0d7c2f42e434e2766d304d917e29b40f0424e8faaaa936bbc3f29" dependencies = [ "anyhow", - "derive_builder 0.20.1", + "derive_builder 0.20.2", "git2", "rustversion", "time", @@ -5448,7 +5435,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229eaddb0050920816cf051e619affaf18caa3dd512de8de5839ccbc8e53abb0" dependencies = [ "anyhow", - "derive_builder 0.20.1", + "derive_builder 0.20.2", "rustversion", ] @@ -5491,9 +5478,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -5502,24 +5489,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -5529,9 +5516,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5539,28 +5526,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -5810,7 +5797,7 @@ checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -5821,7 +5808,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -5832,7 +5819,7 @@ checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -5843,7 +5830,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -6265,7 +6252,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] diff --git a/opossum/examples/parabolic_mirror.rs b/opossum/examples/parabolic_mirror.rs new file mode 100644 index 0000000000000000000000000000000000000000..b60b2646a914a35feb3fa8ebd2fd70a63075551a --- /dev/null +++ b/opossum/examples/parabolic_mirror.rs @@ -0,0 +1,49 @@ +use opossum::{ + analyzers::{AnalyzerType, RayTraceConfig}, + coatings::CoatingType, + degree, + error::OpmResult, + joule, millimeter, + nodes::{ + round_collimated_ray_source, EnergyMeter, NodeGroup, ParabolicMirror, + RayPropagationVisualizer, SpotDiagram, ThinMirror, WaveFront, + }, + optic_node::{Alignable, OpticNode}, + optic_ports::PortType, + OpmDocument, +}; +use std::path::Path; + +fn main() -> OpmResult<()> { + let mut scenery = NodeGroup::default(); + let i_src = scenery.add_node(&round_collimated_ray_source( + millimeter!(20.0), + joule!(1.0), + 3, + )?)?; + let mut mirror1 = ThinMirror::new("mirror 1").with_tilt(degree!(22.5, 0.0, 0.0))?; + mirror1.set_coating( + &PortType::Input, + "input", + &CoatingType::ConstantR { reflectivity: 0.5 }, + )?; + let i_m1 = scenery.add_node(&mirror1)?; + let i_m2 = scenery.add_node( + &ParabolicMirror::new("parabola", millimeter!(-50.0))? + .with_oap_angles(degree!(45.0, 0.0))?, + )?; + let i_prop_vis = scenery.add_node(&RayPropagationVisualizer::default())?; + let i_sd = scenery.add_node(&SpotDiagram::default())?; + let i_wf = scenery.add_node(&WaveFront::default())?; + let i_pm = scenery.add_node(&EnergyMeter::default())?; + scenery.connect_nodes(i_src, "out1", i_m1, "input", millimeter!(100.0))?; + scenery.connect_nodes(i_m1, "reflected", i_m2, "input", millimeter!(100.0))?; + scenery.connect_nodes(i_m2, "reflected", i_prop_vis, "in1", millimeter!(80.0))?; + scenery.connect_nodes(i_prop_vis, "out1", i_sd, "in1", millimeter!(0.1))?; + scenery.connect_nodes(i_sd, "out1", i_wf, "in1", millimeter!(0.1))?; + scenery.connect_nodes(i_wf, "out1", i_pm, "in1", millimeter!(0.1))?; + + let mut doc = OpmDocument::new(scenery); + doc.add_analyzer(AnalyzerType::RayTrace(RayTraceConfig::default())); + doc.save_to_file(Path::new("./opossum/playground/parabolic_mirror.opm")) +} diff --git a/opossum/src/main.rs b/opossum/src/main.rs index d92ab1d5f08d5de2bbbb970a74ad06d564f9130b..f05a81d471264fd1b00538e79b643afb61cc872d 100644 --- a/opossum/src/main.rs +++ b/opossum/src/main.rs @@ -110,11 +110,11 @@ fn opossum() -> OpmResult<()> { let analyzers = document.analyzers(); let scenery = document.scenery_mut(); //create the dot file of the scenery + create_data_dir(&opossum_args.report_directory)?; create_dot_file(&opossum_args.report_directory, scenery)?; if analyzers.is_empty() { info!("No analyzer defined in document. Stopping here."); } else { - create_data_dir(&opossum_args.report_directory)?; for ana in analyzers.iter().enumerate() { let analyzer: &dyn Analyzer = match ana.1 { AnalyzerType::Energy => &EnergyAnalyzer::default(), diff --git a/opossum/src/nodes/mod.rs b/opossum/src/nodes/mod.rs index f58118605c847667357df1c4fddf15074aa41f6e..f463f05b5f6c7aa3ad75472c220ad3f9e1007347 100644 --- a/opossum/src/nodes/mod.rs +++ b/opossum/src/nodes/mod.rs @@ -10,6 +10,7 @@ mod ideal_filter; mod lens; mod node_attr; mod node_group; +mod parabolic_mirror; mod paraxial_surface; mod reference; mod source; @@ -34,6 +35,7 @@ pub use ideal_filter::{FilterType, IdealFilter}; pub use lens::Lens; pub use node_attr::NodeAttr; pub use node_group::{NodeGroup, OpticGraph}; +pub use parabolic_mirror::ParabolicMirror; pub use paraxial_surface::ParaxialSurface; pub use ray_propagation_visualizer::RayPropagationVisualizer; pub use reference::NodeReference; @@ -62,6 +64,7 @@ use uuid::Uuid; /// # Errors /// /// This function will return an [`OpossumError`] if there is no node with the given type. +#[allow(clippy::too_many_lines)] pub fn create_node_ref(node_type: &str, uuid: Option<Uuid>) -> OpmResult<OpticRef> { match node_type { "dummy" => Ok(OpticRef::new( @@ -159,6 +162,11 @@ pub fn create_node_ref(node_type: &str, uuid: Option<Uuid>) -> OpmResult<OpticRe uuid, None, )), + "parabolic mirror" => Ok(OpticRef::new( + Rc::new(RefCell::new(ParabolicMirror::default())), + uuid, + None, + )), _ => Err(OpossumError::Other(format!( "cannot create node type <{node_type}>" ))), diff --git a/opossum/src/nodes/node_group/mod.rs b/opossum/src/nodes/node_group/mod.rs index e159827a2b9ed9b4f0c52a7c8666a67ac35d20ee..0ba27cc703b8f058ef7d52530424b10a9de93cec 100644 --- a/opossum/src/nodes/node_group/mod.rs +++ b/opossum/src/nodes/node_group/mod.rs @@ -29,9 +29,9 @@ use std::{ cell::RefCell, collections::{BTreeMap, HashMap}, io::Write, + process::Stdio, rc::Rc, }; -use tempfile::NamedTempFile; use uom::si::f64::Length; use uuid::Uuid; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -396,17 +396,29 @@ impl NodeGroup { /// This function will return an error if the image generation fails (e.g. program not found, no memory left etc.). pub fn toplevel_dot_svg(&self) -> OpmResult<String> { let dot_string = self.toplevel_dot("")?; - let mut f = NamedTempFile::new() - .map_err(|e| OpossumError::Other(format!("conversion to image failed: {e}")))?; - f.write_all(dot_string.as_bytes()) - .map_err(|e| OpossumError::Other(format!("conversion to image failed: {e}")))?; - let r = std::process::Command::new("dot") - .arg(f.path()) + let mut child = std::process::Command::new("dot") .arg("-Tsvg:cairo") .arg("-Kdot") - .output() + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::null()) + .spawn() + .map_err(|e| OpossumError::Other(format!("conversion to image failed: {e}")))?; + + let Some(child_stdin) = child.stdin.as_mut() else { + return Err(OpossumError::Other( + "conversion to image failed: could not set stdin for graphviz command".into(), + )); + }; + child_stdin + .write_all(dot_string.as_bytes()) .map_err(|e| OpossumError::Other(format!("conversion to image failed: {e}")))?; - let svg_string = String::from_utf8(r.stdout) + + let output = child + .wait_with_output() + .map_err(|e| OpossumError::Other(format!("conversion to image failed: {e}")))?; + + let svg_string = String::from_utf8(output.stdout) .map_err(|e| OpossumError::Other(format!("conversion to image failed: {e}")))?; Ok(svg_string) } diff --git a/opossum/src/nodes/parabolic_mirror.rs b/opossum/src/nodes/parabolic_mirror.rs new file mode 100644 index 0000000000000000000000000000000000000000..915b2679d4f858baf7a8d0e221b1a4c2a9f3ebf5 --- /dev/null +++ b/opossum/src/nodes/parabolic_mirror.rs @@ -0,0 +1,231 @@ +use nalgebra::Point2; +use uom::si::f64::{Angle, Length}; + +use crate::{ + analyzers::{ + energy::AnalysisEnergy, ghostfocus::AnalysisGhostFocus, raytrace::AnalysisRayTrace, + Analyzable, RayTraceConfig, + }, + coatings::CoatingType, + degree, + dottable::Dottable, + error::{OpmResult, OpossumError}, + light_result::LightResult, + lightdata::LightData, + meter, + optic_node::{Alignable, OpticNode, LIDT}, + optic_ports::{OpticPorts, PortType}, + properties::Proptype, + surface::{OpticalSurface, Parabola}, + utils::geom_transformation::Isometry, +}; + +use super::NodeAttr; + +#[derive(Debug, Clone)] +/// An infinitely thin mirror with a spherical (or flat) surface. +/// +/// +/// ## Optical Ports +/// - Inputs +/// - `input` +/// - Outputs +/// - `reflected` +/// +/// ## Properties +/// - `name` +/// - `inverted` +/// - `curvature` +pub struct ParabolicMirror { + node_attr: NodeAttr, + surface: OpticalSurface, +} +impl Default for ParabolicMirror { + /// Create a parabolic mirror with a focal length of 1 meter. + fn default() -> Self { + let mut node_attr = NodeAttr::new("parabolic mirror"); + node_attr + .create_property("focal length", "focal length", None, meter!(-1.0).into()) + .unwrap(); + node_attr + .create_property( + "oap angle x", + "off axis angle around local x axis", + None, + degree!(0.0).into(), + ) + .unwrap(); + node_attr + .create_property( + "oap angle y", + "off axis angle around local y axis", + None, + degree!(0.0).into(), + ) + .unwrap(); + let mut ports = OpticPorts::new(); + ports.add(&PortType::Input, "input").unwrap(); + ports + .set_coating( + &PortType::Input, + "input", + &CoatingType::ConstantR { reflectivity: 1.0 }, + ) + .unwrap(); + ports.add(&PortType::Output, "reflected").unwrap(); + node_attr.set_ports(ports); + + Self { + node_attr, + surface: OpticalSurface::new(Box::new( + Parabola::new(meter!(-1.0), &Isometry::identity()).unwrap(), + )), + } + } +} +impl ParabolicMirror { + /// Creates a new [`ParabolicMirror`] node. + /// + /// This function creates a infinitely thin parabolic mirror with a given focal length. + /// + /// # Errors + /// + /// This function returns an error if the given focal length is zero or not finite. + pub fn new(name: &str, focal_length: Length) -> OpmResult<Self> { + if !focal_length.is_normal() { + return Err(OpossumError::Other( + "focal length must not be 0.0 and finite".into(), + )); + } + let mut parabola = Self::default(); + parabola.node_attr.set_name(name); + parabola + .node_attr + .set_property("focal length", focal_length.into())?; + parabola.update_surfaces()?; + Ok(parabola) + } + /// Returns / modifies a [`ParabolicMirror`] with given off-axis angles. + /// + /// The angles define the off axis angles around the local x and y axis of the node. The given angles denote the full + /// angle between an incoming and a reflected beam. Effectively this introduces a decentering + /// of the node during positioning in 3D space such that the desired angles are met. + /// + /// # Errors + /// + /// This function will return an error if the node properties cannot be set. + pub fn with_oap_angles(mut self, angles: Point2<Angle>) -> OpmResult<Self> { + self.set_property("oap angle x", angles[0].into())?; + self.set_property("oap angle y", angles[1].into())?; + self.update_surfaces()?; + Ok(self) + } +} +impl OpticNode for ParabolicMirror { + fn node_attr(&self) -> &NodeAttr { + &self.node_attr + } + fn node_attr_mut(&mut self) -> &mut NodeAttr { + &mut self.node_attr + } + fn update_surfaces(&mut self) -> OpmResult<()> { + let Ok(Proptype::Length(focal_length)) = self.node_attr.get_property("focal length") else { + return Err(OpossumError::Analysis("cannot read focal length".into())); + }; + let Ok(Proptype::Angle(oap_angle_x)) = self.node_attr.get_property("oap angle x") else { + return Err(OpossumError::Analysis( + "cannot read off axis angle x".into(), + )); + }; + let Ok(Proptype::Angle(oap_angle_y)) = self.node_attr.get_property("oap angle y") else { + return Err(OpossumError::Analysis( + "cannot read off axis angle y".into(), + )); + }; + let mut parabola = Parabola::new(*focal_length, &Isometry::identity())?; + parabola.set_off_axis_angles((*oap_angle_x, *oap_angle_y)); + self.surface = OpticalSurface::new(Box::new(parabola)); + Ok(()) + } + fn get_surface_mut(&mut self, _surf_name: &str) -> &mut OpticalSurface { + &mut self.surface + } +} +impl Alignable for ParabolicMirror {} +impl Dottable for ParabolicMirror { + fn node_color(&self) -> &str { + "chocolate2" + } +} +impl LIDT for ParabolicMirror {} +impl Analyzable for ParabolicMirror {} +impl AnalysisGhostFocus for ParabolicMirror {} +impl AnalysisEnergy for ParabolicMirror { + fn analyze(&mut self, incoming_data: LightResult) -> OpmResult<LightResult> { + let (inport, outport) = if self.inverted() { + ("reflected", "input") + } else { + ("input", "reflected") + }; + let Some(data) = incoming_data.get(inport) else { + return Ok(LightResult::default()); + }; + Ok(LightResult::from([(outport.into(), data.clone())])) + } +} +impl AnalysisRayTrace for ParabolicMirror { + fn analyze( + &mut self, + incoming_data: LightResult, + config: &RayTraceConfig, + ) -> OpmResult<LightResult> { + let (inport, outport) = if self.inverted() { + ("reflected", "input") + } else { + ("input", "reflected") + }; + let Some(data) = incoming_data.get(inport) else { + return Ok(LightResult::default()); + }; + if let LightData::Geometric(mut rays) = data.clone() { + let reflected = if let Some(iso) = self.effective_iso() { + let coating = self + .node_attr() + .ports() + .coating(&PortType::Input, "input") + .unwrap() + .clone(); + let surface = self.get_surface_mut(""); + surface.set_isometry(&iso); + surface.set_coating(coating); + let mut reflected_rays = rays.refract_on_surface(surface, None)?; + if let Some(aperture) = self.ports().aperture(&PortType::Input, inport) { + reflected_rays.apodize(aperture, &iso)?; + reflected_rays.invalidate_by_threshold_energy(config.min_energy_per_ray())?; + reflected_rays + } else { + return Err(OpossumError::OpticPort("input aperture not found".into())); + } + } else { + return Err(OpossumError::Analysis( + "no location for surface defined. Aborting".into(), + )); + }; + let light_data = LightData::Geometric(reflected); + let light_result = LightResult::from([(outport.into(), light_data)]); + Ok(light_result) + } else { + Err(OpossumError::Analysis( + "expected ray data at input port".into(), + )) + } + } + + fn calc_node_position( + &mut self, + incoming_data: LightResult, + config: &RayTraceConfig, + ) -> OpmResult<LightResult> { + AnalysisRayTrace::analyze(self, incoming_data, config) + } +} diff --git a/opossum/src/surface/mod.rs b/opossum/src/surface/mod.rs index 5377bd20449254cd0de52ec11b53f3cecc4c735e..5caf321a38b82013bcd5a9de7b98bca6247189a5 100644 --- a/opossum/src/surface/mod.rs +++ b/opossum/src/surface/mod.rs @@ -4,6 +4,7 @@ //! This module handles only the geometric aspect of an optical surface. So a [`GeoSurface`] has no [`Coating`](crate::coatings::Coating) or //! [`Aperture`](crate::aperture::Aperture)s. mod cylinder; +mod parabola; mod plane; mod sphere; @@ -11,6 +12,7 @@ pub mod hit_map; mod optical_surface; pub use cylinder::Cylinder; pub use optical_surface::OpticalSurface; +pub use parabola::Parabola; pub use plane::Plane; pub use sphere::Sphere; diff --git a/opossum/src/surface/parabola.rs b/opossum/src/surface/parabola.rs new file mode 100644 index 0000000000000000000000000000000000000000..1df78a7c1c33ebafec13d10ac855ae09b9353f7d --- /dev/null +++ b/opossum/src/surface/parabola.rs @@ -0,0 +1,209 @@ +//! Parabolic surface +//! +//! This module implements a parabolic surface with a given focal length and a given z position on the optical axis. + +use crate::{ + degree, + error::{OpmResult, OpossumError}, + meter, radian, + utils::geom_transformation::Isometry, +}; +use nalgebra::{vector, Point3, Vector3}; +use num::Zero; +use roots::{find_roots_quadratic, Roots}; +use uom::si::{ + f64::{Angle, Length, Ratio}, + ratio::basis_point, +}; + +use super::GeoSurface; + +#[derive(Debug, Clone)] +/// A spherical surface with its anchor point on the optical axis. +pub struct Parabola { + focal_length: Length, + isometry: Isometry, + off_axis_angles: (Angle, Angle), +} + +impl Parabola { + /// Create a new [`Parabola`] located and oriented by the given [`Isometry`]. + /// + /// # Errors + /// + /// This function will return an error if the focal length is not normal. + pub fn new(focal_length: Length, isometry: &Isometry) -> OpmResult<Self> { + if !focal_length.is_normal() { + return Err(OpossumError::Other( + "focal length must be != 0.0 and finite".into(), + )); + } + let anchor_isometry = Isometry::new( + Point3::new(Length::zero(), Length::zero(), focal_length), + radian!(0., 0., 0.), + )?; + let isometry = isometry.append(&anchor_isometry); + Ok(Self { + focal_length, + isometry, + off_axis_angles: (Angle::zero(), Angle::zero()), + }) + } + /// Sets the off-axis angles (full refelction) of this [`Parabola`]. + pub fn set_off_axis_angles(&mut self, off_axis_angles: (Angle, Angle)) { + // factor 2. because of full reflection angle <-> angle of incidence + self.off_axis_angles = (off_axis_angles.0 / 2., off_axis_angles.1 / 2.); + } + /// Returns the off axis angles of this [`Parabola`]. + #[must_use] + pub fn off_axis_angles(&self) -> (Angle, Angle) { + self.off_axis_angles + } + fn calc_oap_decenter(&self) -> (Length, Length) { + let f_x = + 2. * self.focal_length / (Ratio::new::<basis_point>(1.) + self.off_axis_angles.0.cos()); + let f_y = + 2. * self.focal_length / (Ratio::new::<basis_point>(1.) + self.off_axis_angles.0.cos()); + let oad_x = f_y * (self.off_axis_angles.1.sin()); + let oad_y = f_x * (self.off_axis_angles.0.sin()); + (oad_x, oad_y) + } +} + +impl GeoSurface for Parabola { + fn calc_intersect_and_normal_do( + &self, + ray: &crate::ray::Ray, + ) -> Option<(Point3<Length>, Vector3<f64>)> { + let dir = ray.direction(); + let pos = vector![ + ray.position().x.value, + ray.position().y.value, + ray.position().z.value + ]; + let f_length = self.focal_length.value; + let is_back_propagating = dir.z.is_sign_negative(); + // parabola formula (at origin) + // x^2 + y^2 - 4fz = 0 + // + // insert ray (p: position, d: direction): + // (p_x+t*d_x)^2 + (p_y+t*d_y)^2 - 4f*(p_z+t*d_z) = 0 + // This translates into the qudratic equation + // at^2 + bt + c = 0 with + // a = d_x^2+d_y^2 + // b = 2* (p_x*d_x + p_y*d_y - 2*f*d_z) + // c = p_x^2 + p_y^2 - 4f*p_z + let a = dir.x.mul_add(dir.x, dir.y * dir.y); + let b = 2. * (2. * f_length).mul_add(-dir.z, pos.x.mul_add(dir.x, pos.y * dir.y)); + let c = (4. * f_length).mul_add(-pos.z, pos.x.mul_add(pos.x, pos.y * pos.y)); + // Solve t of qudaratic equation + let roots = find_roots_quadratic(a, b, c); + let intersection_point = match roots { + // no intersection + Roots::No(_) => return None, + // "just touching" intersection + Roots::One(t) => { + if t[0] >= 0.0 { + pos + t[0] * dir + } else { + return None; + } + } + // "regular" intersection + Roots::Two(t) => { + let real_t = if self.focal_length.is_sign_positive() { + // convex surface => use min t + if is_back_propagating { + f64::max(t[0], t[1]) + } else { + f64::min(t[0], t[1]) + } + } else { + // concave surface => use max t + if is_back_propagating { + f64::min(t[0], t[1]) + } else { + f64::max(t[0], t[1]) + } + }; + if real_t.is_sign_negative() { + // surface behind beam + return None; + } + pos + real_t * dir + } + _ => unreachable!(), + }; + // calc surface normal + // calculate grad F(x,y,z) =(2* p_x, 2* p_y, -4 * f) + let normal_vector = vector![ + 2. * intersection_point.x, + 2. * intersection_point.y, + -4. * f_length + ]; + Some(( + meter!( + intersection_point.x, + intersection_point.y, + intersection_point.z + ), + -1.0 * normal_vector, + )) + } + fn isometry(&self) -> &Isometry { + &self.isometry + } + fn set_isometry(&mut self, isometry: &Isometry) { + let oap_decenter = self.calc_oap_decenter(); + let oap_iso = Isometry::new( + Point3::new(oap_decenter.0, oap_decenter.1, Length::zero()), + degree!(0.0, 0.0, 0.0), + ) + .unwrap(); + let total_iso = isometry.append(&oap_iso); + self.isometry = total_iso; + } + fn box_clone(&self) -> Box<dyn GeoSurface> { + Box::new(self.clone()) + } +} + +#[cfg(test)] +mod test { + use nalgebra::vector; + + use super::Parabola; + use crate::{ + degree, joule, meter, millimeter, nanometer, ray::Ray, surface::GeoSurface, + utils::geom_transformation::Isometry, + }; + + #[test] + fn intersect() { + let parabola = Parabola::new(meter!(-1.0), &Isometry::identity()).unwrap(); + let ray = Ray::new_collimated(meter!(-1.0, -1.0, -10.0), nanometer!(1000.0), joule!(1.0)) + .unwrap(); + let intersection = parabola.calc_intersect_and_normal_do(&ray).unwrap(); + assert_eq!(intersection.0, meter!(-1.0, -1.0, -0.5)); + assert_eq!(intersection.1, vector![2.0, 2.0, -4.]); + } + #[test] + fn intersect_ray_through_focus() { + let parabola = Parabola::new(meter!(-1.0), &Isometry::identity()).unwrap(); + let direction = vector![0.0, 1.0, 1. - 0.25]; + let ray = Ray::new( + meter!(0.0, 0.0, -1.0), + direction, + nanometer!(1000.0), + joule!(1.0), + ) + .unwrap(); + dbg!(parabola.calc_intersect_and_normal_do(&ray)); + } + #[test] + fn off_axis_decenter() { + let mut parabola = Parabola::new(millimeter!(-50.0), &Isometry::identity()).unwrap(); + parabola.set_off_axis_angles((degree!(22.5), degree!(0.0))); + dbg!(parabola.calc_oap_decenter()); + } +} diff --git a/opossum/src/surface/sphere.rs b/opossum/src/surface/sphere.rs index eb148c59ecf07e2152c2fbab0fbcd891f1ff2017..0895d0ecdd0195662ceae6eef58b2317c9d9369b 100644 --- a/opossum/src/surface/sphere.rs +++ b/opossum/src/surface/sphere.rs @@ -62,11 +62,6 @@ impl Sphere { let isometry = isometry.append(&anchor_isometry); Ok(Self { radius, isometry }) } - /// Returns the center position of this [`Sphere`] - #[must_use] - pub fn get_pos(&self) -> Point3<Length> { - self.isometry.transform_point(&Point3::origin()) - } } impl GeoSurface for Sphere { fn calc_intersect_and_normal_do(&self, ray: &Ray) -> Option<(Point3<Length>, Vector3<f64>)> { @@ -194,11 +189,9 @@ mod test { let s = Sphere::new(millimeter!(2.0), &iso).unwrap(); assert_eq!(s.radius, millimeter!(2.0)); - assert_eq!(s.get_pos(), millimeter!(0.0, 0.0, 3.0)); let s = Sphere::new(millimeter!(-2.0), &iso).unwrap(); assert_eq!(s.radius, millimeter!(-2.0)); - assert_eq!(s.get_pos(), millimeter!(0.0, 0.0, -1.0)); } #[test] fn new_at_position() { @@ -229,7 +222,6 @@ mod test { let s = Sphere::new_at_position(millimeter!(2.0), millimeter!(1.0, 2.0, 3.0)).unwrap(); assert_eq!(s.radius, millimeter!(2.0)); - assert_eq!(s.get_pos(), millimeter!(1.0, 2.0, 5.0)); } #[test] fn intersect_positive_on_axis_forward() { diff --git a/opossum/test b/opossum/test new file mode 100644 index 0000000000000000000000000000000000000000..da1b18e37b125fd2530d4db80b5c2f25bf1a1a15 Binary files /dev/null and b/opossum/test differ