cosmol-viewer 0.1.4.dev3__tar.gz → 0.1.5.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/Cargo.lock +38 -53
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/Cargo.toml +6 -6
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/PKG-INFO +1 -1
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/Cargo.toml +1 -2
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/lib.rs +33 -24
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/parser/sdf.rs +6 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/scene.rs +7 -5
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/canvas.rs +17 -6
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shapes/molecules.rs +64 -27
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shapes/sphere.rs +4 -2
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shapes/stick.rs +2 -2
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/utils.rs +29 -6
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/python/cosmol_viewer.pyi +4 -2
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/python/src/shapes.rs +8 -5
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/wasm/Cargo.toml +4 -5
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/wasm/src/lib.rs +31 -4
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/pyproject.toml +1 -1
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/README.md +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/parser/mod.rs +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/bg_fragment.glsl +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/bg_vertex.glsl +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/fragment.glsl +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/mod.rs +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/vertex.glsl +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/vertex_sphere.glsl +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/vertex_stick.glsl +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shapes/mod.rs +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/python/Cargo.toml +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/python/README.md +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/python/build.rs +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/python/src/lib.rs +0 -0
- {cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/python/src/parser.rs +0 -0
|
@@ -759,7 +759,7 @@ dependencies = [
|
|
|
759
759
|
|
|
760
760
|
[[package]]
|
|
761
761
|
name = "cosmol_viewer"
|
|
762
|
-
version = "0.1.
|
|
762
|
+
version = "0.1.5-nightly.1"
|
|
763
763
|
dependencies = [
|
|
764
764
|
"bytemuck",
|
|
765
765
|
"cosmol_viewer_core",
|
|
@@ -772,7 +772,7 @@ dependencies = [
|
|
|
772
772
|
|
|
773
773
|
[[package]]
|
|
774
774
|
name = "cosmol_viewer_core"
|
|
775
|
-
version = "0.1.
|
|
775
|
+
version = "0.1.5-nightly.1"
|
|
776
776
|
dependencies = [
|
|
777
777
|
"bytemuck",
|
|
778
778
|
"eframe",
|
|
@@ -784,7 +784,6 @@ dependencies = [
|
|
|
784
784
|
"serde",
|
|
785
785
|
"serde_json",
|
|
786
786
|
"serde_repr",
|
|
787
|
-
"wasm-bindgen-futures",
|
|
788
787
|
]
|
|
789
788
|
|
|
790
789
|
[[package]]
|
|
@@ -802,7 +801,7 @@ dependencies = [
|
|
|
802
801
|
|
|
803
802
|
[[package]]
|
|
804
803
|
name = "cosmol_viewer_wasm"
|
|
805
|
-
version = "0.
|
|
804
|
+
version = "0.0.0"
|
|
806
805
|
dependencies = [
|
|
807
806
|
"base64",
|
|
808
807
|
"cosmol_viewer_core",
|
|
@@ -923,9 +922,9 @@ checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
|
|
|
923
922
|
|
|
924
923
|
[[package]]
|
|
925
924
|
name = "ecolor"
|
|
926
|
-
version = "0.33.
|
|
925
|
+
version = "0.33.2"
|
|
927
926
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
928
|
-
checksum = "
|
|
927
|
+
checksum = "084980ebede2fb1ad6c4f54285b3e489052ef2b6aa4016e4c19349417adc75c5"
|
|
929
928
|
dependencies = [
|
|
930
929
|
"bytemuck",
|
|
931
930
|
"emath",
|
|
@@ -933,9 +932,9 @@ dependencies = [
|
|
|
933
932
|
|
|
934
933
|
[[package]]
|
|
935
934
|
name = "eframe"
|
|
936
|
-
version = "0.33.
|
|
935
|
+
version = "0.33.2"
|
|
937
936
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
938
|
-
checksum = "
|
|
937
|
+
checksum = "4f60ee3c69cd01d5725b4ef476ed6a3a6009968c57843a2f1beb96f021e4a54b"
|
|
939
938
|
dependencies = [
|
|
940
939
|
"ahash",
|
|
941
940
|
"bytemuck",
|
|
@@ -968,9 +967,9 @@ dependencies = [
|
|
|
968
967
|
|
|
969
968
|
[[package]]
|
|
970
969
|
name = "egui"
|
|
971
|
-
version = "0.33.
|
|
970
|
+
version = "0.33.2"
|
|
972
971
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
973
|
-
checksum = "
|
|
972
|
+
checksum = "b75645894de4ca1695ab3ab7201c7953bb95c1725aafeefa6822dc901ad2a81b"
|
|
974
973
|
dependencies = [
|
|
975
974
|
"accesskit",
|
|
976
975
|
"ahash",
|
|
@@ -986,9 +985,9 @@ dependencies = [
|
|
|
986
985
|
|
|
987
986
|
[[package]]
|
|
988
987
|
name = "egui-wgpu"
|
|
989
|
-
version = "0.33.
|
|
988
|
+
version = "0.33.2"
|
|
990
989
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
991
|
-
checksum = "
|
|
990
|
+
checksum = "acdaac35a6e0ff458aaa5776b2bda578e38334a9d1258f7795042a70372745b7"
|
|
992
991
|
dependencies = [
|
|
993
992
|
"ahash",
|
|
994
993
|
"bytemuck",
|
|
@@ -1006,9 +1005,9 @@ dependencies = [
|
|
|
1006
1005
|
|
|
1007
1006
|
[[package]]
|
|
1008
1007
|
name = "egui-winit"
|
|
1009
|
-
version = "0.33.
|
|
1008
|
+
version = "0.33.2"
|
|
1010
1009
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1011
|
-
checksum = "
|
|
1010
|
+
checksum = "4772ed5f16fa8ec2ba295e58f62b58ee83fcf49e67ec13d2b7ddf4e9a2dea34e"
|
|
1012
1011
|
dependencies = [
|
|
1013
1012
|
"accesskit_winit",
|
|
1014
1013
|
"arboard",
|
|
@@ -1028,9 +1027,9 @@ dependencies = [
|
|
|
1028
1027
|
|
|
1029
1028
|
[[package]]
|
|
1030
1029
|
name = "egui_extras"
|
|
1031
|
-
version = "0.33.
|
|
1030
|
+
version = "0.33.2"
|
|
1032
1031
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1033
|
-
checksum = "
|
|
1032
|
+
checksum = "550e844e608e356f4ad6843c510aa9bb5838b427e4700ed0056e9746ceeed866"
|
|
1034
1033
|
dependencies = [
|
|
1035
1034
|
"ahash",
|
|
1036
1035
|
"egui",
|
|
@@ -1042,9 +1041,9 @@ dependencies = [
|
|
|
1042
1041
|
|
|
1043
1042
|
[[package]]
|
|
1044
1043
|
name = "egui_glow"
|
|
1045
|
-
version = "0.33.
|
|
1044
|
+
version = "0.33.2"
|
|
1046
1045
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1047
|
-
checksum = "
|
|
1046
|
+
checksum = "17b94ff67a1d18933fff2519f5f57c388f932c093036c381fb9ae2853b3e1e09"
|
|
1048
1047
|
dependencies = [
|
|
1049
1048
|
"bytemuck",
|
|
1050
1049
|
"egui",
|
|
@@ -1065,9 +1064,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
|
|
1065
1064
|
|
|
1066
1065
|
[[package]]
|
|
1067
1066
|
name = "emath"
|
|
1068
|
-
version = "0.33.
|
|
1067
|
+
version = "0.33.2"
|
|
1069
1068
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1070
|
-
checksum = "
|
|
1069
|
+
checksum = "0e561352ae95c22ad179fb56c38d6e6eecd86cf4925cf5c70e738dd01df9b620"
|
|
1071
1070
|
dependencies = [
|
|
1072
1071
|
"bytemuck",
|
|
1073
1072
|
]
|
|
@@ -1121,9 +1120,9 @@ dependencies = [
|
|
|
1121
1120
|
|
|
1122
1121
|
[[package]]
|
|
1123
1122
|
name = "epaint"
|
|
1124
|
-
version = "0.33.
|
|
1123
|
+
version = "0.33.2"
|
|
1125
1124
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1126
|
-
checksum = "
|
|
1125
|
+
checksum = "a909ce8cee63e8350fb0c251ad39277a5b24f19add60787e84a3b3ab3f2bd83a"
|
|
1127
1126
|
dependencies = [
|
|
1128
1127
|
"ab_glyph",
|
|
1129
1128
|
"ahash",
|
|
@@ -1139,9 +1138,9 @@ dependencies = [
|
|
|
1139
1138
|
|
|
1140
1139
|
[[package]]
|
|
1141
1140
|
name = "epaint_default_fonts"
|
|
1142
|
-
version = "0.33.
|
|
1141
|
+
version = "0.33.2"
|
|
1143
1142
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1144
|
-
checksum = "
|
|
1143
|
+
checksum = "ad9649446c23368ae138716910e3e28143995691b598fbb9de16b42b0722cbcc"
|
|
1145
1144
|
|
|
1146
1145
|
[[package]]
|
|
1147
1146
|
name = "equator"
|
|
@@ -1859,9 +1858,9 @@ dependencies = [
|
|
|
1859
1858
|
|
|
1860
1859
|
[[package]]
|
|
1861
1860
|
name = "js-sys"
|
|
1862
|
-
version = "0.3.
|
|
1861
|
+
version = "0.3.82"
|
|
1863
1862
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1864
|
-
checksum = "
|
|
1863
|
+
checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
|
|
1865
1864
|
dependencies = [
|
|
1866
1865
|
"once_cell",
|
|
1867
1866
|
"wasm-bindgen",
|
|
@@ -3708,9 +3707,9 @@ dependencies = [
|
|
|
3708
3707
|
|
|
3709
3708
|
[[package]]
|
|
3710
3709
|
name = "wasm-bindgen"
|
|
3711
|
-
version = "0.2.
|
|
3710
|
+
version = "0.2.105"
|
|
3712
3711
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3713
|
-
checksum = "
|
|
3712
|
+
checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
|
|
3714
3713
|
dependencies = [
|
|
3715
3714
|
"cfg-if",
|
|
3716
3715
|
"once_cell",
|
|
@@ -3719,25 +3718,11 @@ dependencies = [
|
|
|
3719
3718
|
"wasm-bindgen-shared",
|
|
3720
3719
|
]
|
|
3721
3720
|
|
|
3722
|
-
[[package]]
|
|
3723
|
-
name = "wasm-bindgen-backend"
|
|
3724
|
-
version = "0.2.104"
|
|
3725
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3726
|
-
checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19"
|
|
3727
|
-
dependencies = [
|
|
3728
|
-
"bumpalo",
|
|
3729
|
-
"log",
|
|
3730
|
-
"proc-macro2",
|
|
3731
|
-
"quote",
|
|
3732
|
-
"syn",
|
|
3733
|
-
"wasm-bindgen-shared",
|
|
3734
|
-
]
|
|
3735
|
-
|
|
3736
3721
|
[[package]]
|
|
3737
3722
|
name = "wasm-bindgen-futures"
|
|
3738
|
-
version = "0.4.
|
|
3723
|
+
version = "0.4.55"
|
|
3739
3724
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3740
|
-
checksum = "
|
|
3725
|
+
checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0"
|
|
3741
3726
|
dependencies = [
|
|
3742
3727
|
"cfg-if",
|
|
3743
3728
|
"js-sys",
|
|
@@ -3748,9 +3733,9 @@ dependencies = [
|
|
|
3748
3733
|
|
|
3749
3734
|
[[package]]
|
|
3750
3735
|
name = "wasm-bindgen-macro"
|
|
3751
|
-
version = "0.2.
|
|
3736
|
+
version = "0.2.105"
|
|
3752
3737
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3753
|
-
checksum = "
|
|
3738
|
+
checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
|
|
3754
3739
|
dependencies = [
|
|
3755
3740
|
"quote",
|
|
3756
3741
|
"wasm-bindgen-macro-support",
|
|
@@ -3758,22 +3743,22 @@ dependencies = [
|
|
|
3758
3743
|
|
|
3759
3744
|
[[package]]
|
|
3760
3745
|
name = "wasm-bindgen-macro-support"
|
|
3761
|
-
version = "0.2.
|
|
3746
|
+
version = "0.2.105"
|
|
3762
3747
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3763
|
-
checksum = "
|
|
3748
|
+
checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
|
|
3764
3749
|
dependencies = [
|
|
3750
|
+
"bumpalo",
|
|
3765
3751
|
"proc-macro2",
|
|
3766
3752
|
"quote",
|
|
3767
3753
|
"syn",
|
|
3768
|
-
"wasm-bindgen-backend",
|
|
3769
3754
|
"wasm-bindgen-shared",
|
|
3770
3755
|
]
|
|
3771
3756
|
|
|
3772
3757
|
[[package]]
|
|
3773
3758
|
name = "wasm-bindgen-shared"
|
|
3774
|
-
version = "0.2.
|
|
3759
|
+
version = "0.2.105"
|
|
3775
3760
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3776
|
-
checksum = "
|
|
3761
|
+
checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
|
|
3777
3762
|
dependencies = [
|
|
3778
3763
|
"unicode-ident",
|
|
3779
3764
|
]
|
|
@@ -3889,9 +3874,9 @@ dependencies = [
|
|
|
3889
3874
|
|
|
3890
3875
|
[[package]]
|
|
3891
3876
|
name = "web-sys"
|
|
3892
|
-
version = "0.3.
|
|
3877
|
+
version = "0.3.82"
|
|
3893
3878
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3894
|
-
checksum = "
|
|
3879
|
+
checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1"
|
|
3895
3880
|
dependencies = [
|
|
3896
3881
|
"js-sys",
|
|
3897
3882
|
"wasm-bindgen",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[workspace.package]
|
|
2
2
|
edition = "2024"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.5-nightly.1"
|
|
4
4
|
authors = ["9028 wjt@cosmol.org"]
|
|
5
5
|
repository = "https://github.com/COSMol-repl/COSMol-viewer"
|
|
6
6
|
homepage = "https://github.com/COSMol-repl/COSMol-viewer"
|
|
@@ -13,13 +13,13 @@ resolver = "2"
|
|
|
13
13
|
members = ["crates/python"]
|
|
14
14
|
|
|
15
15
|
[workspace.dependencies]
|
|
16
|
-
cosmol_viewer = { version = "0.1.
|
|
17
|
-
cosmol_viewer_core = { version = "0.1.
|
|
16
|
+
cosmol_viewer = { version = "0.1.5-nightly.1", path = "cosmol_viewer"}
|
|
17
|
+
cosmol_viewer_core = { version = "0.1.5-nightly.1", path = "crates/core" }
|
|
18
18
|
|
|
19
|
-
eframe = { version = "0.33.0", features = ["wayland","x11"] }
|
|
20
19
|
pyo3 = { version = "0.27.1", features = ["extension-module", "abi3-py37"] }
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
eframe = { version = "0.33.2", features = ["wayland","x11"] }
|
|
21
|
+
egui-winit = { version = "0.33.2", features = ["wayland","x11"] }
|
|
22
|
+
egui_extras = { version = "0.33.2" }
|
|
23
23
|
serde = { version = "1.0.228" , features = ["derive"] }
|
|
24
24
|
serde_json = "1.0.145"
|
|
25
25
|
base64 = "0.22.1"
|
|
@@ -12,9 +12,8 @@ serde_json.workspace = true
|
|
|
12
12
|
egui_extras.workspace = true
|
|
13
13
|
serde.workspace = true
|
|
14
14
|
glam = { version = "0.30.8" , features = ["serde"] }
|
|
15
|
-
bytemuck = "1.
|
|
15
|
+
bytemuck = "1.24.0"
|
|
16
16
|
serde_repr = "0.1.20"
|
|
17
|
-
wasm-bindgen-futures = "0.4.54"
|
|
18
17
|
once_cell = "1.21.3"
|
|
19
18
|
image = "0.25.8"
|
|
20
19
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
mod shader;
|
|
2
|
-
use std::{
|
|
3
|
-
sync::{Arc, Mutex},
|
|
4
|
-
};
|
|
2
|
+
use std::sync::{Arc, Mutex};
|
|
5
3
|
|
|
6
4
|
pub mod parser;
|
|
7
5
|
pub mod utils;
|
|
@@ -14,16 +12,16 @@ use eframe::{
|
|
|
14
12
|
|
|
15
13
|
use shader::Canvas;
|
|
16
14
|
|
|
17
|
-
pub use crate::utils::Shape;
|
|
15
|
+
pub use crate::utils::{Logger, RustLogger, Shape};
|
|
18
16
|
pub mod shapes;
|
|
19
17
|
use crate::{scene::Scene, utils::Frames};
|
|
20
18
|
|
|
21
19
|
pub mod scene;
|
|
22
20
|
use image::{ImageBuffer, Rgba};
|
|
23
21
|
|
|
24
|
-
pub struct AppWrapper(pub Arc<Mutex<Option<App
|
|
22
|
+
pub struct AppWrapper<L: Logger>(pub Arc<Mutex<Option<App<L>>>>);
|
|
25
23
|
|
|
26
|
-
impl eframe::App for AppWrapper {
|
|
24
|
+
impl<L: Logger> eframe::App for AppWrapper<L> {
|
|
27
25
|
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
|
28
26
|
if let Some(app) = &mut *self.0.lock().unwrap() {
|
|
29
27
|
app.update(ctx, frame);
|
|
@@ -31,36 +29,41 @@ impl eframe::App for AppWrapper {
|
|
|
31
29
|
}
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
pub struct App {
|
|
35
|
-
canvas: Canvas
|
|
32
|
+
pub struct App<L: Logger> {
|
|
33
|
+
canvas: Canvas<L>,
|
|
36
34
|
gl: Option<Arc<eframe::glow::Context>>,
|
|
37
35
|
pub ctx: egui::Context,
|
|
38
36
|
screenshot_requested: bool,
|
|
39
37
|
screenshot_result: Option<(Arc<egui::ColorImage>, egui::TextureHandle)>,
|
|
38
|
+
logger: L,
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
impl App {
|
|
43
|
-
pub fn new(cc: &eframe::CreationContext<'_>, scene: Scene) -> Self {
|
|
41
|
+
impl<L: Logger> App<L> {
|
|
42
|
+
pub fn new(cc: &eframe::CreationContext<'_>, scene: Scene, logger: L) -> Self {
|
|
43
|
+
logger.log("Creating new viewer app...");
|
|
44
44
|
let gl = cc.gl.clone();
|
|
45
|
-
let canvas = Canvas::new(gl.as_ref().unwrap().clone(), scene).unwrap();
|
|
45
|
+
let canvas = Canvas::new(gl.as_ref().unwrap().clone(), scene, logger).unwrap();
|
|
46
46
|
App {
|
|
47
47
|
gl,
|
|
48
48
|
canvas,
|
|
49
49
|
ctx: cc.egui_ctx.clone(),
|
|
50
50
|
screenshot_requested: false,
|
|
51
51
|
screenshot_result: None,
|
|
52
|
+
logger,
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
pub fn new_play(cc: &eframe::CreationContext<'_>, scene: Frames) -> Self {
|
|
56
|
+
pub fn new_play(cc: &eframe::CreationContext<'_>, scene: Frames, logger: L) -> Self {
|
|
57
|
+
logger.log("Creating new viewer app...");
|
|
56
58
|
let gl = cc.gl.clone();
|
|
57
|
-
let canvas = Canvas::new_play(gl.as_ref().unwrap().clone(), scene).unwrap();
|
|
59
|
+
let canvas = Canvas::new_play(gl.as_ref().unwrap().clone(), scene, logger).unwrap();
|
|
58
60
|
App {
|
|
59
61
|
gl,
|
|
60
62
|
canvas,
|
|
61
63
|
ctx: cc.egui_ctx.clone(),
|
|
62
64
|
screenshot_requested: false,
|
|
63
65
|
screenshot_result: None,
|
|
66
|
+
logger,
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
69
|
|
|
@@ -93,7 +96,7 @@ fn color_image_to_rgba_bytes(image: &egui::ColorImage) -> Vec<u8> {
|
|
|
93
96
|
image.pixels.iter().flat_map(|c| c.to_array()).collect()
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
impl eframe::App for App {
|
|
99
|
+
impl<L: Logger> eframe::App for App<L> {
|
|
97
100
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
|
98
101
|
#[cfg(not(target_arch = "wasm32"))]
|
|
99
102
|
egui_extras::install_image_loaders(ctx);
|
|
@@ -141,16 +144,16 @@ impl eframe::App for App {
|
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
pub struct NativeGuiViewer {
|
|
144
|
-
pub app: Arc<Mutex<Option<App
|
|
147
|
+
pub app: Arc<Mutex<Option<App<RustLogger>>>>,
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
impl NativeGuiViewer {
|
|
148
151
|
pub fn render(scene: &Scene, width: f32, height: f32) -> Self {
|
|
152
|
+
use std::time::Duration;
|
|
149
153
|
use std::{
|
|
150
154
|
sync::{Arc, Mutex},
|
|
151
155
|
thread,
|
|
152
156
|
};
|
|
153
|
-
use std::time::Duration;
|
|
154
157
|
|
|
155
158
|
#[cfg(not(target_arch = "wasm32"))]
|
|
156
159
|
use eframe::{
|
|
@@ -160,14 +163,14 @@ impl NativeGuiViewer {
|
|
|
160
163
|
|
|
161
164
|
// let viewport_size = scene.viewport.unwrap_or([800, 500]);
|
|
162
165
|
|
|
163
|
-
let app: Arc<Mutex<Option<App
|
|
166
|
+
let app: Arc<Mutex<Option<App<RustLogger>>>> = Arc::new(Mutex::new(None));
|
|
164
167
|
let app_clone = Arc::clone(&app);
|
|
165
168
|
|
|
166
169
|
let scene = Arc::new(Mutex::new(scene.clone()));
|
|
167
170
|
#[cfg(not(target_arch = "wasm32"))]
|
|
168
171
|
thread::spawn(move || {
|
|
169
|
-
use std::process;
|
|
170
172
|
use eframe::{EventLoopBuilderHook, run_native};
|
|
173
|
+
use std::process;
|
|
171
174
|
let event_loop_builder: Option<EventLoopBuilderHook> =
|
|
172
175
|
Some(Box::new(|event_loop_builder| {
|
|
173
176
|
#[cfg(target_family = "windows")]
|
|
@@ -200,7 +203,7 @@ impl NativeGuiViewer {
|
|
|
200
203
|
native_options,
|
|
201
204
|
Box::new(move |cc| {
|
|
202
205
|
let mut guard = app_clone.lock().unwrap();
|
|
203
|
-
*guard = Some(App::new(cc, scene.lock().unwrap().clone()));
|
|
206
|
+
*guard = Some(App::new(cc, scene.lock().unwrap().clone(), RustLogger));
|
|
204
207
|
Ok(Box::new(AppWrapper(app_clone.clone())))
|
|
205
208
|
}),
|
|
206
209
|
);
|
|
@@ -260,7 +263,14 @@ impl NativeGuiViewer {
|
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
|
|
263
|
-
pub fn play(
|
|
266
|
+
pub fn play(
|
|
267
|
+
frames: Vec<Scene>,
|
|
268
|
+
interval: f32,
|
|
269
|
+
loops: i64,
|
|
270
|
+
width: f32,
|
|
271
|
+
height: f32,
|
|
272
|
+
smooth: bool,
|
|
273
|
+
) {
|
|
264
274
|
use std::{
|
|
265
275
|
sync::{Arc, Mutex},
|
|
266
276
|
thread,
|
|
@@ -279,7 +289,7 @@ impl NativeGuiViewer {
|
|
|
279
289
|
egui::{Vec2, ViewportBuilder},
|
|
280
290
|
};
|
|
281
291
|
|
|
282
|
-
let app: Arc<Mutex<Option<App
|
|
292
|
+
let app: Arc<Mutex<Option<App<RustLogger>>>> = Arc::new(Mutex::new(None));
|
|
283
293
|
let app_clone = Arc::clone(&app);
|
|
284
294
|
|
|
285
295
|
#[cfg(not(target_arch = "wasm32"))]
|
|
@@ -319,14 +329,13 @@ impl NativeGuiViewer {
|
|
|
319
329
|
native_options,
|
|
320
330
|
Box::new(move |cc| {
|
|
321
331
|
let mut guard = app_clone.lock().unwrap();
|
|
322
|
-
*guard = Some(App::new_play(cc, frames));
|
|
332
|
+
*guard = Some(App::new_play(cc, frames, RustLogger));
|
|
323
333
|
Ok(Box::new(AppWrapper(app_clone.clone())))
|
|
324
334
|
}),
|
|
325
335
|
);
|
|
326
336
|
process::exit(0);
|
|
327
337
|
});
|
|
328
338
|
|
|
329
|
-
loop {
|
|
330
|
-
}
|
|
339
|
+
loop {}
|
|
331
340
|
}
|
|
332
341
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
pub use crate::utils::{Logger, RustLogger};
|
|
2
|
+
|
|
1
3
|
#[derive(Debug, Clone)]
|
|
2
4
|
pub struct Atom {
|
|
3
5
|
pub atom: String,
|
|
@@ -24,6 +26,10 @@ pub struct ParserOptions {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
pub fn parse_sdf(sdf: &str, options: &ParserOptions) -> MoleculeData {
|
|
29
|
+
_parse_sdf(sdf, options, RustLogger)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pub fn _parse_sdf(sdf: &str, options: &ParserOptions, logger: impl Logger) -> MoleculeData {
|
|
27
33
|
let lines: Vec<&str> = sdf.lines().collect();
|
|
28
34
|
if lines.len() > 3 && lines[3].len() > 38 {
|
|
29
35
|
let version = lines[3][34..39].trim();
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
use crate::utils::Logger;
|
|
1
2
|
use std::collections::HashMap;
|
|
2
3
|
|
|
3
4
|
use serde::{Deserialize, Serialize};
|
|
4
5
|
|
|
5
6
|
use crate::{
|
|
6
|
-
|
|
7
|
+
Shape,
|
|
8
|
+
shader::CameraState,
|
|
9
|
+
utils::{self, InstanceData, Interpolatable, IntoInstanceGroups, ShapeKind, ToMesh},
|
|
7
10
|
};
|
|
8
11
|
|
|
9
12
|
#[derive(Deserialize, Serialize, Clone)]
|
|
@@ -71,7 +74,6 @@ impl InstanceGroups {
|
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
|
|
75
77
|
impl Scene {
|
|
76
78
|
pub fn _get_meshes(&self) -> Vec<utils::MeshData> {
|
|
77
79
|
self.named_shapes
|
|
@@ -136,13 +138,13 @@ impl Scene {
|
|
|
136
138
|
}
|
|
137
139
|
|
|
138
140
|
impl Interpolatable for Scene {
|
|
139
|
-
fn interpolate(&self, other: &Self, t: f32) -> Self {
|
|
141
|
+
fn interpolate(&self, other: &Self, t: f32, logger: impl Logger) -> Self {
|
|
140
142
|
let named_shapes = self
|
|
141
143
|
.named_shapes
|
|
142
144
|
.iter()
|
|
143
145
|
.map(|(k, v)| {
|
|
144
146
|
let other_shape = &other.named_shapes[k];
|
|
145
|
-
(k.clone(), v.interpolate(other_shape, t))
|
|
147
|
+
(k.clone(), v.interpolate(other_shape, t, logger))
|
|
146
148
|
})
|
|
147
149
|
.collect();
|
|
148
150
|
|
|
@@ -150,7 +152,7 @@ impl Interpolatable for Scene {
|
|
|
150
152
|
.unnamed_shapes
|
|
151
153
|
.iter()
|
|
152
154
|
.zip(&other.unnamed_shapes)
|
|
153
|
-
.map(|(a, b)| a.interpolate(b, t))
|
|
155
|
+
.map(|(a, b)| a.interpolate(b, t, logger))
|
|
154
156
|
.collect();
|
|
155
157
|
|
|
156
158
|
Self {
|
|
@@ -17,31 +17,38 @@ use crate::scene::StickInstance;
|
|
|
17
17
|
use crate::shapes::Sphere;
|
|
18
18
|
use crate::shapes::Stick;
|
|
19
19
|
use crate::utils::Frames;
|
|
20
|
-
use crate::utils::Interpolatable;
|
|
20
|
+
use crate::utils::{Interpolatable, Logger};
|
|
21
21
|
|
|
22
|
-
pub struct Canvas {
|
|
22
|
+
pub struct Canvas<L: Logger> {
|
|
23
23
|
shader: Arc<Mutex<Shader>>,
|
|
24
24
|
camera_state: CameraState,
|
|
25
25
|
frames: Option<Frames>,
|
|
26
26
|
interpolate_enabled: bool,
|
|
27
|
+
logger: L,
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
impl Canvas {
|
|
30
|
-
pub fn new<'a>(gl: Arc<eframe::glow::Context>, scene: Scene) -> Option<Self> {
|
|
30
|
+
impl<L: Logger> Canvas<L> {
|
|
31
|
+
pub fn new<'a>(gl: Arc<eframe::glow::Context>, scene: Scene, logger: L) -> Option<Self> {
|
|
31
32
|
Some(Self {
|
|
32
33
|
shader: Arc::new(Mutex::new(Shader::new(&gl, scene)?)),
|
|
33
34
|
camera_state: CameraState::new(1.0),
|
|
34
35
|
frames: None,
|
|
35
36
|
interpolate_enabled: false,
|
|
37
|
+
logger,
|
|
36
38
|
})
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
pub fn new_play<'a>(gl: Arc<eframe::glow::Context>, frames: Frames) -> Option<Self> {
|
|
41
|
+
pub fn new_play<'a>(gl: Arc<eframe::glow::Context>, frames: Frames, logger: L) -> Option<Self> {
|
|
42
|
+
if frames.frames.is_empty() {
|
|
43
|
+
logger.error("No frames provided");
|
|
44
|
+
return None;
|
|
45
|
+
}
|
|
40
46
|
Some(Self {
|
|
41
47
|
shader: Arc::new(Mutex::new(Shader::new(&gl, frames.frames[0].clone())?)),
|
|
42
48
|
camera_state: CameraState::new(1.0),
|
|
43
49
|
interpolate_enabled: frames.smooth,
|
|
44
50
|
frames: Some(frames),
|
|
51
|
+
logger,
|
|
45
52
|
})
|
|
46
53
|
}
|
|
47
54
|
|
|
@@ -100,7 +107,11 @@ impl Canvas {
|
|
|
100
107
|
} else {
|
|
101
108
|
// 这里是原先的插值 / 非插值逻辑
|
|
102
109
|
if self.interpolate_enabled {
|
|
103
|
-
frames.frames[frame_a_index].interpolate(
|
|
110
|
+
frames.frames[frame_a_index].interpolate(
|
|
111
|
+
&frames.frames[frame_b_index],
|
|
112
|
+
t,
|
|
113
|
+
self.logger,
|
|
114
|
+
)
|
|
104
115
|
} else {
|
|
105
116
|
frames.frames[frame_a_index].clone()
|
|
106
117
|
}
|
|
@@ -6,7 +6,9 @@ use crate::{
|
|
|
6
6
|
parser::sdf::MoleculeData,
|
|
7
7
|
scene::{InstanceGroups, SphereInstance},
|
|
8
8
|
shapes::{sphere::Sphere, stick::Stick},
|
|
9
|
-
utils::{
|
|
9
|
+
utils::{
|
|
10
|
+
Interaction, Interpolatable, IntoInstanceGroups, Logger, MeshData, VisualShape, VisualStyle,
|
|
11
|
+
},
|
|
10
12
|
};
|
|
11
13
|
|
|
12
14
|
use std::{collections::HashMap, str::FromStr};
|
|
@@ -102,7 +104,29 @@ pub struct Molecules {
|
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
impl Interpolatable for Molecules {
|
|
105
|
-
fn interpolate(&self, other: &Self, t: f32) -> Self {
|
|
107
|
+
fn interpolate(&self, other: &Self, t: f32, logger: impl Logger) -> Self {
|
|
108
|
+
// 检查原子数量是否匹配
|
|
109
|
+
if self.atoms.len() != other.atoms.len() {
|
|
110
|
+
logger.error(format!(
|
|
111
|
+
"Interpolation aborted: atom count differs (self: {}, other: {}). \
|
|
112
|
+
Smooth interpolation requires scenes with identical atom structures.",
|
|
113
|
+
self.atoms.len(),
|
|
114
|
+
other.atoms.len()
|
|
115
|
+
));
|
|
116
|
+
panic!("Smooth interpolation requires matching atom structures.");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 检查键数量是否匹配(可选,根据需要)
|
|
120
|
+
if self.bonds.len() != other.bonds.len() {
|
|
121
|
+
logger.error(format!(
|
|
122
|
+
"Interpolation aborted: bond topology differs (self: {}, other: {}). \
|
|
123
|
+
Smooth interpolation cannot proceed with different bonding graphs.",
|
|
124
|
+
self.bonds.len(),
|
|
125
|
+
other.bonds.len()
|
|
126
|
+
));
|
|
127
|
+
panic!("Smooth interpolation requires matching bond topology.");
|
|
128
|
+
}
|
|
129
|
+
|
|
106
130
|
// 原子坐标插值
|
|
107
131
|
let atoms: Vec<[f32; 3]> = self
|
|
108
132
|
.atoms
|
|
@@ -192,11 +216,9 @@ impl Molecules {
|
|
|
192
216
|
}
|
|
193
217
|
}
|
|
194
218
|
|
|
195
|
-
|
|
196
|
-
/// is at the origin (0.0, 0.0, 0.0).
|
|
197
|
-
pub fn centered(mut self) -> Self {
|
|
219
|
+
pub fn get_center(&self) -> [f32; 3] {
|
|
198
220
|
if self.atoms.is_empty() {
|
|
199
|
-
return
|
|
221
|
+
return [0.0; 3];
|
|
200
222
|
}
|
|
201
223
|
|
|
202
224
|
// 1. 累加所有原子坐标
|
|
@@ -213,16 +235,27 @@ impl Molecules {
|
|
|
213
235
|
center[1] /= count;
|
|
214
236
|
center[2] /= count;
|
|
215
237
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
238
|
+
center
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/// Centers the molecule by translating all atoms so that the geometric center
|
|
242
|
+
/// is at the origin (0.0, 0.0, 0.0).
|
|
243
|
+
pub fn centered(mut self) -> Self {
|
|
244
|
+
let center = self.get_center();
|
|
245
|
+
for atom in &mut self.atoms {
|
|
246
|
+
atom[0] -= center[0];
|
|
247
|
+
atom[1] -= center[1];
|
|
248
|
+
atom[2] -= center[2];
|
|
221
249
|
}
|
|
222
250
|
|
|
223
251
|
self
|
|
224
252
|
}
|
|
225
253
|
|
|
254
|
+
pub fn reset_color(mut self) -> Self {
|
|
255
|
+
self.style_mut().color = None;
|
|
256
|
+
self
|
|
257
|
+
}
|
|
258
|
+
|
|
226
259
|
pub fn to_mesh(&self, scale: f32) -> MeshData {
|
|
227
260
|
return MeshData::default();
|
|
228
261
|
|
|
@@ -480,22 +513,26 @@ impl IntoInstanceGroups for Molecules {
|
|
|
480
513
|
let d = 0.22;
|
|
481
514
|
|
|
482
515
|
// 颜色和半径与原来一致
|
|
483
|
-
let color_a =
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
516
|
+
let color_a = self.style.color.unwrap_or(
|
|
517
|
+
match self
|
|
518
|
+
.atom_types
|
|
519
|
+
.get(a as usize)
|
|
520
|
+
.unwrap_or(&AtomType::Unknown)
|
|
521
|
+
{
|
|
522
|
+
AtomType::C => [0.75, 0.75, 0.75],
|
|
523
|
+
other => other.color(),
|
|
524
|
+
},
|
|
525
|
+
);
|
|
526
|
+
let color_b = self.style.color.unwrap_or(
|
|
527
|
+
match self
|
|
528
|
+
.atom_types
|
|
529
|
+
.get(b as usize)
|
|
530
|
+
.unwrap_or(&AtomType::Unknown)
|
|
531
|
+
{
|
|
532
|
+
AtomType::C => [0.75, 0.75, 0.75],
|
|
533
|
+
other => other.color(),
|
|
534
|
+
},
|
|
535
|
+
);
|
|
499
536
|
|
|
500
537
|
// 根据键类型生成多个 stick
|
|
501
538
|
let (num_sticks, radius) = match bond_type {
|
|
@@ -3,7 +3,9 @@ use serde::{Deserialize, Serialize};
|
|
|
3
3
|
use crate::{
|
|
4
4
|
Shape,
|
|
5
5
|
scene::{Instance, InstanceGroups, Scene, SphereInstance},
|
|
6
|
-
utils::{
|
|
6
|
+
utils::{
|
|
7
|
+
Interaction, Interpolatable, IntoInstanceGroups, Logger, MeshData, VisualShape, VisualStyle,
|
|
8
|
+
},
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
use once_cell::sync::Lazy;
|
|
@@ -31,7 +33,7 @@ pub struct Sphere {
|
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
impl Interpolatable for Sphere {
|
|
34
|
-
fn interpolate(&self, other: &Self, t: f32) -> Self {
|
|
36
|
+
fn interpolate(&self, other: &Self, t: f32, logger: impl Logger) -> Self {
|
|
35
37
|
Self {
|
|
36
38
|
center: [
|
|
37
39
|
self.center[0] * (1.0 - t) + other.center[0] * t,
|
|
@@ -7,7 +7,7 @@ use crate::{
|
|
|
7
7
|
Shape,
|
|
8
8
|
scene::{Scene, StickInstance},
|
|
9
9
|
shapes::sphere::MeshTemplate,
|
|
10
|
-
utils::{Interaction, Interpolatable, MeshData, VisualShape, VisualStyle},
|
|
10
|
+
utils::{Interaction, Interpolatable, Logger, MeshData, VisualShape, VisualStyle},
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
static STICK_TEMPLATE_CACHE: Lazy<Mutex<HashMap<u32, MeshTemplate>>> =
|
|
@@ -25,7 +25,7 @@ pub struct Stick {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
impl Interpolatable for Stick {
|
|
28
|
-
fn interpolate(&self, other: &Self, t: f32) -> Self {
|
|
28
|
+
fn interpolate(&self, other: &Self, t: f32, logger: impl Logger) -> Self {
|
|
29
29
|
Self {
|
|
30
30
|
start: [
|
|
31
31
|
self.start[0] * (1.0 - t) + other.start[0] * t,
|
|
@@ -6,6 +6,27 @@ use crate::{
|
|
|
6
6
|
shapes::{Molecules, Sphere, Stick},
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
pub trait Logger: Send + Sync + Copy {
|
|
10
|
+
fn log(&self, message: impl std::fmt::Display);
|
|
11
|
+
fn error(&self, message: impl std::fmt::Display);
|
|
12
|
+
fn warn(&self, message: impl std::fmt::Display);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#[derive(Clone, Copy)]
|
|
16
|
+
pub struct RustLogger;
|
|
17
|
+
|
|
18
|
+
impl Logger for RustLogger {
|
|
19
|
+
fn log(&self, message: impl std::fmt::Display) {
|
|
20
|
+
println!("[LOG] {}", message);
|
|
21
|
+
}
|
|
22
|
+
fn warn(&self, message: impl std::fmt::Display) {
|
|
23
|
+
eprintln!("[WARN] {}", message);
|
|
24
|
+
}
|
|
25
|
+
fn error(&self, message: impl std::fmt::Display) {
|
|
26
|
+
eprintln!("[ERROR] {}", message);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
9
30
|
#[derive(Serialize, Deserialize, Debug, Clone, Default, Copy)]
|
|
10
31
|
pub struct VisualStyle {
|
|
11
32
|
pub color: Option<[f32; 3]>,
|
|
@@ -25,7 +46,7 @@ pub struct Interaction {
|
|
|
25
46
|
|
|
26
47
|
pub trait Interpolatable {
|
|
27
48
|
/// t ∈ [0.0, 1.0],返回两个实例之间的插值
|
|
28
|
-
fn interpolate(&self, other: &Self, t: f32) -> Self;
|
|
49
|
+
fn interpolate(&self, other: &Self, t: f32, logger: impl Logger) -> Self;
|
|
29
50
|
}
|
|
30
51
|
|
|
31
52
|
// -------------------- 图元结构体 --------------------------
|
|
@@ -53,11 +74,13 @@ pub struct InstanceData {
|
|
|
53
74
|
}
|
|
54
75
|
|
|
55
76
|
impl Interpolatable for Shape {
|
|
56
|
-
fn interpolate(&self, other: &Self, t: f32) -> Self {
|
|
77
|
+
fn interpolate(&self, other: &Self, t: f32, logger: impl Logger) -> Self {
|
|
57
78
|
match (self, other) {
|
|
58
|
-
(Shape::Sphere(a), Shape::Sphere(b)) => Shape::Sphere(a.interpolate(b, t)),
|
|
59
|
-
(Shape::Stick(a), Shape::Stick(b)) => Shape::Stick(a.interpolate(b, t)),
|
|
60
|
-
(Shape::Molecules(a), Shape::Molecules(b)) =>
|
|
79
|
+
(Shape::Sphere(a), Shape::Sphere(b)) => Shape::Sphere(a.interpolate(b, t, logger)),
|
|
80
|
+
(Shape::Stick(a), Shape::Stick(b)) => Shape::Stick(a.interpolate(b, t, logger)),
|
|
81
|
+
(Shape::Molecules(a), Shape::Molecules(b)) => {
|
|
82
|
+
Shape::Molecules(a.interpolate(b, t, logger))
|
|
83
|
+
}
|
|
61
84
|
_ => self.clone(), // 如果类型不匹配,可以选择不插值或做默认处理
|
|
62
85
|
}
|
|
63
86
|
}
|
|
@@ -75,7 +98,7 @@ impl IntoInstanceGroups for Shape {
|
|
|
75
98
|
let m_groups = m.to_instance_group(scale);
|
|
76
99
|
groups.merge(m_groups);
|
|
77
100
|
}
|
|
78
|
-
_ => {}
|
|
101
|
+
_ => {}
|
|
79
102
|
}
|
|
80
103
|
groups
|
|
81
104
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Optional, Union, List
|
|
1
|
+
from typing import Optional, Union, List
|
|
2
2
|
|
|
3
3
|
def parse_sdf(
|
|
4
4
|
sdf: str,
|
|
@@ -201,7 +201,7 @@ class Viewer:
|
|
|
201
201
|
- loops: Number of loops to repeat (-1 for infinite).
|
|
202
202
|
- width: The viewport width in pixels.
|
|
203
203
|
- height: The viewport height in pixels.
|
|
204
|
-
- smooth: Whether to smooth the animation by
|
|
204
|
+
- smooth: Whether to smooth the animation by
|
|
205
205
|
interpolating between frames.
|
|
206
206
|
|
|
207
207
|
# Returns
|
|
@@ -306,10 +306,12 @@ class Molecules:
|
|
|
306
306
|
"""
|
|
307
307
|
|
|
308
308
|
def __init__(self, molecule_data: "MoleculeData") -> None: ...
|
|
309
|
+
def get_center(self) -> List[float]: ...
|
|
309
310
|
def centered(self) -> "Molecules": ...
|
|
310
311
|
def color(self, color: List[float]) -> "Molecules": ...
|
|
311
312
|
def color_rgba(self, color: List[float]) -> "Molecules": ...
|
|
312
313
|
def opacity(self, opacity: float) -> "Molecules": ...
|
|
314
|
+
def reset_color(self) -> "Molecules": ...
|
|
313
315
|
|
|
314
316
|
class MoleculeData:
|
|
315
317
|
"""
|
|
@@ -7,13 +7,13 @@ use pyo3::{PyRefMut, pyclass, pymethods};
|
|
|
7
7
|
|
|
8
8
|
#[pyclass(name = "Sphere")]
|
|
9
9
|
/// Sphere(center: [f32; 3], radius: f32)
|
|
10
|
-
///
|
|
10
|
+
///
|
|
11
11
|
/// A sphere in the scene.
|
|
12
|
-
///
|
|
12
|
+
///
|
|
13
13
|
/// # Arguments
|
|
14
14
|
/// * `center` - The center of the sphere.
|
|
15
15
|
/// * `radius` - The radius of the sphere.
|
|
16
|
-
///
|
|
16
|
+
///
|
|
17
17
|
/// # Examples
|
|
18
18
|
/// ```
|
|
19
19
|
/// scene = Scene()
|
|
@@ -21,7 +21,7 @@ use pyo3::{PyRefMut, pyclass, pymethods};
|
|
|
21
21
|
/// scene.add_shape(sphere, id)
|
|
22
22
|
/// viewer = Viewer.render(scene)
|
|
23
23
|
/// ```
|
|
24
|
-
///
|
|
24
|
+
///
|
|
25
25
|
#[derive(Clone)]
|
|
26
26
|
pub struct PySphere {
|
|
27
27
|
pub inner: Sphere,
|
|
@@ -123,6 +123,10 @@ impl PyMolecules {
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
pub fn get_center(slf: PyRefMut<'_, Self>) -> [f32; 3] {
|
|
127
|
+
slf.inner.clone().get_center()
|
|
128
|
+
}
|
|
129
|
+
|
|
126
130
|
pub fn centered(mut slf: PyRefMut<'_, Self>) -> PyRefMut<'_, Self> {
|
|
127
131
|
slf.inner = slf.inner.clone().centered();
|
|
128
132
|
slf
|
|
@@ -138,7 +142,6 @@ impl PyMolecules {
|
|
|
138
142
|
slf
|
|
139
143
|
}
|
|
140
144
|
|
|
141
|
-
|
|
142
145
|
pub fn opacity(mut slf: PyRefMut<'_, Self>, opacity: f32) -> PyRefMut<'_, Self> {
|
|
143
146
|
slf.inner = slf.inner.clone().opacity(opacity);
|
|
144
147
|
slf
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "cosmol_viewer_wasm"
|
|
3
|
-
|
|
4
|
-
edition = "2024"
|
|
3
|
+
edition.workspace = true
|
|
5
4
|
publish = false
|
|
6
5
|
|
|
7
6
|
[dependencies]
|
|
@@ -12,9 +11,9 @@ log = "0.4.28"
|
|
|
12
11
|
|
|
13
12
|
uuid = { version = "1.18.1", features = ["v4"], optional = true }
|
|
14
13
|
eframe = { workspace = true, optional = true }
|
|
15
|
-
wasm-bindgen-futures = { version = "0.4.
|
|
16
|
-
web-sys = { version = "0.3.
|
|
17
|
-
wasm-bindgen = { version = "0.2.
|
|
14
|
+
wasm-bindgen-futures = { version = "0.4.55", optional = true }
|
|
15
|
+
web-sys = { version = "0.3.82", features = ["HtmlCanvasElement", "console","Window"], optional = true }
|
|
16
|
+
wasm-bindgen = { version = "0.2.105", optional = true }
|
|
18
17
|
gloo-timers = { version = "0.3.0", features = ["futures-core", "futures"], optional = true }
|
|
19
18
|
pyo3 = { workspace = true, optional = true }
|
|
20
19
|
base64 = { workspace = true, optional = true }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
use cosmol_viewer_core::App;
|
|
2
2
|
use cosmol_viewer_core::scene::Scene;
|
|
3
|
-
use cosmol_viewer_core::utils::Frames;
|
|
3
|
+
use cosmol_viewer_core::utils::{Frames, Logger};
|
|
4
4
|
#[cfg(feature = "js_bridge")]
|
|
5
5
|
use serde::Serialize;
|
|
6
6
|
use std::sync::Arc;
|
|
@@ -292,11 +292,38 @@ impl WebRunner {
|
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
+
#[cfg(feature = "wasm")]
|
|
296
|
+
#[derive(Clone, Copy)]
|
|
297
|
+
pub struct WasmLogger;
|
|
298
|
+
|
|
299
|
+
#[cfg(feature = "wasm")]
|
|
300
|
+
impl Logger for WasmLogger {
|
|
301
|
+
fn log(&self, message: impl std::fmt::Display) {
|
|
302
|
+
web_sys::console::log_1(&JsValue::from_str(&message.to_string()));
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
fn warn(&self, message: impl std::fmt::Display) {
|
|
306
|
+
web_sys::console::warn_1(&JsValue::from_str(&message.to_string()));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
fn error(&self, message: impl std::fmt::Display) {
|
|
310
|
+
let msg = message.to_string();
|
|
311
|
+
|
|
312
|
+
// Send to console
|
|
313
|
+
web_sys::console::error_1(&JsValue::from_str(&msg));
|
|
314
|
+
|
|
315
|
+
// Show browser alert
|
|
316
|
+
if let Some(window) = web_sys::window() {
|
|
317
|
+
window.alert_with_message(&msg).ok();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
295
322
|
#[cfg(feature = "wasm")]
|
|
296
323
|
#[wasm_bindgen]
|
|
297
324
|
pub struct WebHandle {
|
|
298
325
|
runner: WebRunner,
|
|
299
|
-
app: Arc<Mutex<Option<App
|
|
326
|
+
app: Arc<Mutex<Option<App<WasmLogger>>>>,
|
|
300
327
|
}
|
|
301
328
|
|
|
302
329
|
#[cfg(feature = "wasm")]
|
|
@@ -337,7 +364,7 @@ impl WebHandle {
|
|
|
337
364
|
use cosmol_viewer_core::AppWrapper;
|
|
338
365
|
|
|
339
366
|
let mut guard = app.lock().unwrap();
|
|
340
|
-
*guard = Some(App::new(cc, scene));
|
|
367
|
+
*guard = Some(App::new(cc, scene, WasmLogger));
|
|
341
368
|
Ok(Box::new(AppWrapper(app.clone())))
|
|
342
369
|
}),
|
|
343
370
|
)
|
|
@@ -384,7 +411,7 @@ impl WebHandle {
|
|
|
384
411
|
use cosmol_viewer_core::AppWrapper;
|
|
385
412
|
|
|
386
413
|
let mut guard = app.lock().unwrap();
|
|
387
|
-
*guard = Some(App::new_play(cc, frames));
|
|
414
|
+
*guard = Some(App::new_play(cc, frames, WasmLogger));
|
|
388
415
|
Ok(Box::new(AppWrapper(app.clone())))
|
|
389
416
|
}),
|
|
390
417
|
)
|
|
File without changes
|
|
File without changes
|
{cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/bg_fragment.glsl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/vertex_sphere.glsl
RENAMED
|
File without changes
|
{cosmol_viewer-0.1.4.dev3 → cosmol_viewer-0.1.5.dev1}/crates/core/src/shader/vertex_stick.glsl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|