cosmol-viewer 0.1.3.dev1__tar.gz → 0.1.3.dev3__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.
Potentially problematic release.
This version of cosmol-viewer might be problematic. Click here for more details.
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/Cargo.lock +20 -19
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/Cargo.toml +3 -3
- cosmol_viewer-0.1.3.dev3/PKG-INFO +179 -0
- cosmol_viewer-0.1.3.dev3/README.md +170 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/lib.rs +1 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shader/canvas.rs +2 -1
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shapes/sphere.rs +0 -5
- cosmol_viewer-0.1.3.dev3/crates/python/README.md +170 -0
- cosmol_viewer-0.1.3.dev3/crates/python/cosmol_viewer.pyi +315 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/python/src/lib.rs +3 -179
- cosmol_viewer-0.1.3.dev3/crates/python/src/shapes.rs +146 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/wasm/Cargo.toml +2 -2
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/wasm/src/lib.rs +9 -5
- cosmol_viewer-0.1.3.dev3/crates/wasm/vendor/pako.min.js +2 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/pyproject.toml +2 -1
- cosmol_viewer-0.1.3.dev1/PKG-INFO +0 -6
- cosmol_viewer-0.1.3.dev1/crates/python/README.md +0 -65
- cosmol_viewer-0.1.3.dev1/crates/python/src/shapes.rs +0 -287
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/Cargo.toml +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/parser/mod.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/parser/sdf.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/scene.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shader/bg_fragment.glsl +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shader/bg_vertex.glsl +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shader/fragment.glsl +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shader/mod.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shader/vertex.glsl +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shapes/mod.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shapes/molecules.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/shapes/stick.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/core/src/utils.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/python/Cargo.toml +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/python/build.rs +0 -0
- {cosmol_viewer-0.1.3.dev1 → cosmol_viewer-0.1.3.dev3}/crates/python/src/parser.rs +0 -0
|
@@ -727,7 +727,7 @@ dependencies = [
|
|
|
727
727
|
|
|
728
728
|
[[package]]
|
|
729
729
|
name = "cosmol_viewer"
|
|
730
|
-
version = "0.1.3-nightly.
|
|
730
|
+
version = "0.1.3-nightly.3"
|
|
731
731
|
dependencies = [
|
|
732
732
|
"bytemuck",
|
|
733
733
|
"cosmol_viewer_core",
|
|
@@ -740,7 +740,7 @@ dependencies = [
|
|
|
740
740
|
|
|
741
741
|
[[package]]
|
|
742
742
|
name = "cosmol_viewer_core"
|
|
743
|
-
version = "0.1.3-nightly.
|
|
743
|
+
version = "0.1.3-nightly.3"
|
|
744
744
|
dependencies = [
|
|
745
745
|
"bytemuck",
|
|
746
746
|
"eframe",
|
|
@@ -770,7 +770,7 @@ dependencies = [
|
|
|
770
770
|
|
|
771
771
|
[[package]]
|
|
772
772
|
name = "cosmol_viewer_wasm"
|
|
773
|
-
version = "0.1.3-nightly.
|
|
773
|
+
version = "0.1.3-nightly.3"
|
|
774
774
|
dependencies = [
|
|
775
775
|
"base64",
|
|
776
776
|
"cosmol_viewer_core",
|
|
@@ -1746,9 +1746,9 @@ checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
|
|
|
1746
1746
|
|
|
1747
1747
|
[[package]]
|
|
1748
1748
|
name = "js-sys"
|
|
1749
|
-
version = "0.3.
|
|
1749
|
+
version = "0.3.81"
|
|
1750
1750
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1751
|
-
checksum = "
|
|
1751
|
+
checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305"
|
|
1752
1752
|
dependencies = [
|
|
1753
1753
|
"once_cell",
|
|
1754
1754
|
"wasm-bindgen",
|
|
@@ -3501,21 +3501,22 @@ dependencies = [
|
|
|
3501
3501
|
|
|
3502
3502
|
[[package]]
|
|
3503
3503
|
name = "wasm-bindgen"
|
|
3504
|
-
version = "0.2.
|
|
3504
|
+
version = "0.2.104"
|
|
3505
3505
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3506
|
-
checksum = "
|
|
3506
|
+
checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d"
|
|
3507
3507
|
dependencies = [
|
|
3508
3508
|
"cfg-if",
|
|
3509
3509
|
"once_cell",
|
|
3510
3510
|
"rustversion",
|
|
3511
3511
|
"wasm-bindgen-macro",
|
|
3512
|
+
"wasm-bindgen-shared",
|
|
3512
3513
|
]
|
|
3513
3514
|
|
|
3514
3515
|
[[package]]
|
|
3515
3516
|
name = "wasm-bindgen-backend"
|
|
3516
|
-
version = "0.2.
|
|
3517
|
+
version = "0.2.104"
|
|
3517
3518
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3518
|
-
checksum = "
|
|
3519
|
+
checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19"
|
|
3519
3520
|
dependencies = [
|
|
3520
3521
|
"bumpalo",
|
|
3521
3522
|
"log",
|
|
@@ -3527,9 +3528,9 @@ dependencies = [
|
|
|
3527
3528
|
|
|
3528
3529
|
[[package]]
|
|
3529
3530
|
name = "wasm-bindgen-futures"
|
|
3530
|
-
version = "0.4.
|
|
3531
|
+
version = "0.4.54"
|
|
3531
3532
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3532
|
-
checksum = "
|
|
3533
|
+
checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c"
|
|
3533
3534
|
dependencies = [
|
|
3534
3535
|
"cfg-if",
|
|
3535
3536
|
"js-sys",
|
|
@@ -3540,9 +3541,9 @@ dependencies = [
|
|
|
3540
3541
|
|
|
3541
3542
|
[[package]]
|
|
3542
3543
|
name = "wasm-bindgen-macro"
|
|
3543
|
-
version = "0.2.
|
|
3544
|
+
version = "0.2.104"
|
|
3544
3545
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3545
|
-
checksum = "
|
|
3546
|
+
checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119"
|
|
3546
3547
|
dependencies = [
|
|
3547
3548
|
"quote",
|
|
3548
3549
|
"wasm-bindgen-macro-support",
|
|
@@ -3550,9 +3551,9 @@ dependencies = [
|
|
|
3550
3551
|
|
|
3551
3552
|
[[package]]
|
|
3552
3553
|
name = "wasm-bindgen-macro-support"
|
|
3553
|
-
version = "0.2.
|
|
3554
|
+
version = "0.2.104"
|
|
3554
3555
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3555
|
-
checksum = "
|
|
3556
|
+
checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7"
|
|
3556
3557
|
dependencies = [
|
|
3557
3558
|
"proc-macro2",
|
|
3558
3559
|
"quote",
|
|
@@ -3563,9 +3564,9 @@ dependencies = [
|
|
|
3563
3564
|
|
|
3564
3565
|
[[package]]
|
|
3565
3566
|
name = "wasm-bindgen-shared"
|
|
3566
|
-
version = "0.2.
|
|
3567
|
+
version = "0.2.104"
|
|
3567
3568
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3568
|
-
checksum = "
|
|
3569
|
+
checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1"
|
|
3569
3570
|
dependencies = [
|
|
3570
3571
|
"unicode-ident",
|
|
3571
3572
|
]
|
|
@@ -3681,9 +3682,9 @@ dependencies = [
|
|
|
3681
3682
|
|
|
3682
3683
|
[[package]]
|
|
3683
3684
|
name = "web-sys"
|
|
3684
|
-
version = "0.3.
|
|
3685
|
+
version = "0.3.81"
|
|
3685
3686
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3686
|
-
checksum = "
|
|
3687
|
+
checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120"
|
|
3687
3688
|
dependencies = [
|
|
3688
3689
|
"js-sys",
|
|
3689
3690
|
"wasm-bindgen",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[workspace.package]
|
|
2
2
|
edition = "2024"
|
|
3
|
-
version = "0.1.3-nightly.
|
|
3
|
+
version = "0.1.3-nightly.3"
|
|
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,8 +13,8 @@ resolver = "2"
|
|
|
13
13
|
members = ["crates/python"]
|
|
14
14
|
|
|
15
15
|
[workspace.dependencies]
|
|
16
|
-
cosmol_viewer = { version = "0.1.3-nightly.
|
|
17
|
-
cosmol_viewer_core = { version = "0.1.3-nightly.
|
|
16
|
+
cosmol_viewer = { version = "0.1.3-nightly.3", path = "cosmol_viewer"}
|
|
17
|
+
cosmol_viewer_core = { version = "0.1.3-nightly.3", path = "crates/core" }
|
|
18
18
|
|
|
19
19
|
eframe = { version = "0.32.0", features = ["wayland","x11"] }
|
|
20
20
|
pyo3 = { version = "0.25.1", features = ["extension-module", "abi3-py37"] }
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cosmol-viewer
|
|
3
|
+
Version: 0.1.3.dev3
|
|
4
|
+
Summary: Molecular visualization tools
|
|
5
|
+
Author-email: 95028 <wjt@cosmol.org>
|
|
6
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
7
|
+
Project-URL: Repository, https://github.com/COSMol-repl/COSMol-viewer
|
|
8
|
+
|
|
9
|
+
# COSMol-viewer
|
|
10
|
+
|
|
11
|
+
<div align="center">
|
|
12
|
+
<a href="https://crates.io/crates/cosmol_viewer">
|
|
13
|
+
<img src="https://img.shields.io/crates/v/cosmol_viewer.svg" alt="crates.io Latest Release"/>
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://pypi.org/project/cosmol_viewer/">
|
|
16
|
+
<img src="https://img.shields.io/pypi/v/cosmol_viewer.svg" alt="PyPi Latest Release"/>
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://cosmol-repl.github.io/COSMol-viewer">
|
|
19
|
+
<img src="https://img.shields.io/badge/docs-latest-blue.svg" alt="Documentation Status"/>
|
|
20
|
+
</a>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
**COSMol-viewer** is a high-performance molecular visualization library, written in **Rust** and powered by **WebGPU**, designed for seamless integration into **Python** workflows.
|
|
24
|
+
|
|
25
|
+
- ⚡ **High-speed rendering** — GPU-accelerated performance at native speed
|
|
26
|
+
- 🧬 **Flexible input** — Load structures from `.sdf`, `.pdb`, or dynamically generated coordinates
|
|
27
|
+
- 📓 **Notebook-ready** — Fully compatible with Jupyter and Google Colab, ideal for teaching, research, and interactive demos
|
|
28
|
+
- 🔁 **Dynamic visualization** — Update molecular structures on-the-fly or play smooth preloaded animations
|
|
29
|
+
- 🎨 **Customizable** — Fine-grained control of rendering styles, camera, and scene parameters
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
pip install cosmol-viewer
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
45
|
+
|
|
46
|
+
# === Step 1: Load and render a molecule ===
|
|
47
|
+
with open("molecule.sdf", "r") as f:
|
|
48
|
+
sdf = f.read()
|
|
49
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
50
|
+
|
|
51
|
+
scene = Scene()
|
|
52
|
+
scene.scale(0.1)
|
|
53
|
+
scene.add_shape(mol, "mol")
|
|
54
|
+
|
|
55
|
+
viewer = Viewer.render(scene, width=600, height=400) # Launch viewer
|
|
56
|
+
|
|
57
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
58
|
+
_ = input() # Keep the viewer open until you decide to close
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Animation Modes
|
|
64
|
+
|
|
65
|
+
COSMol-viewer supports **two complementary animation workflows**, depending on whether you prefer **real-time updates** or **preloaded playback**.
|
|
66
|
+
|
|
67
|
+
### 1. Real-Time Updates (Frame-by-Frame Streaming)
|
|
68
|
+
|
|
69
|
+
Update the molecule directly inside an existing scene:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import time
|
|
73
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
74
|
+
|
|
75
|
+
scene = Scene()
|
|
76
|
+
scene.scale(0.1)
|
|
77
|
+
|
|
78
|
+
# Initial load
|
|
79
|
+
with open("frames/frame_1.sdf", "r") as f:
|
|
80
|
+
sdf = f.read()
|
|
81
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
82
|
+
scene.add_shape(mol, "mol")
|
|
83
|
+
|
|
84
|
+
viewer = Viewer.render(scene, width=600, height=400)
|
|
85
|
+
|
|
86
|
+
# Update in real time
|
|
87
|
+
for i in range(2, 10):
|
|
88
|
+
with open(f"frames/frame_{i}.sdf", "r") as f:
|
|
89
|
+
sdf = f.read()
|
|
90
|
+
updated_mol = Molecules(parse_sdf(sdf)).centered()
|
|
91
|
+
|
|
92
|
+
scene.update_shape("mol", updated_mol)
|
|
93
|
+
viewer.update(scene)
|
|
94
|
+
|
|
95
|
+
time.sleep(0.033) # ~30 FPS
|
|
96
|
+
|
|
97
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
98
|
+
_ = input()
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Use cases:**
|
|
102
|
+
- Visualizing the *progress* of a simulation step-by-step
|
|
103
|
+
- Interactive experiments or streaming scenarios where frames are not known in advance
|
|
104
|
+
|
|
105
|
+
**Trade-offs:**
|
|
106
|
+
- ✅ Low memory usage — no need to preload frames
|
|
107
|
+
- ⚠️ Playback smoothness depends on computation / I/O speed → may stutter if frame generation is slow
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### 2. Preloaded Playback (One-Shot Animation) (Start from 0.1.3)
|
|
112
|
+
|
|
113
|
+
Load all frames into memory first, then play them back smoothly:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
117
|
+
|
|
118
|
+
frames = []
|
|
119
|
+
interval = 0.033 # ~30 FPS
|
|
120
|
+
|
|
121
|
+
# Preload all frames
|
|
122
|
+
for i in range(1, 10):
|
|
123
|
+
with open(f"frames/frame_{i}.sdf", "r") as f:
|
|
124
|
+
sdf = f.read()
|
|
125
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
126
|
+
|
|
127
|
+
scene = Scene()
|
|
128
|
+
scene.scale(0.1)
|
|
129
|
+
scene.add_shape(mol, "mol")
|
|
130
|
+
frames.append(scene)
|
|
131
|
+
|
|
132
|
+
# Playback once
|
|
133
|
+
Viewer.play(frames, interval=interval, loops=1, width=600, height=400)
|
|
134
|
+
|
|
135
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
136
|
+
_ = input()
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Use cases:**
|
|
140
|
+
- Smooth, stable playback for presentations or teaching
|
|
141
|
+
- Demonstrating precomputed trajectories (e.g., molecular dynamics snapshots)
|
|
142
|
+
|
|
143
|
+
**Trade-offs:**
|
|
144
|
+
- ✅ Very smooth playback, independent of computation speed
|
|
145
|
+
- ⚠️ Requires preloading all frames → higher memory usage
|
|
146
|
+
- ⚠️ Longer initial load time for large trajectories
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Choosing the Right Mode
|
|
151
|
+
|
|
152
|
+
- ✅ Use **real-time updates** if your frames are generated on-the-fly or memory is limited
|
|
153
|
+
- ✅ Use **preloaded playback** if you want guaranteed smooth animations and can preload your trajectory
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Exiting the Viewer
|
|
158
|
+
|
|
159
|
+
> **Important:** The viewer is bound to the Python process.
|
|
160
|
+
> When your script finishes, the rendering window will close automatically.
|
|
161
|
+
|
|
162
|
+
To keep the visualization alive until you are ready to exit, always add:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
166
|
+
_ = input()
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
This ensures:
|
|
170
|
+
- The window stays open for inspection
|
|
171
|
+
- The user decides when to end visualization
|
|
172
|
+
- Prevents premature termination at the end of the script
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Documentation
|
|
177
|
+
|
|
178
|
+
For API reference and advanced usage, please see the [latest documentation](https://cosmol-repl.github.io/COSMol-viewer).
|
|
179
|
+
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# COSMol-viewer
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
<a href="https://crates.io/crates/cosmol_viewer">
|
|
5
|
+
<img src="https://img.shields.io/crates/v/cosmol_viewer.svg" alt="crates.io Latest Release"/>
|
|
6
|
+
</a>
|
|
7
|
+
<a href="https://pypi.org/project/cosmol_viewer/">
|
|
8
|
+
<img src="https://img.shields.io/pypi/v/cosmol_viewer.svg" alt="PyPi Latest Release"/>
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://cosmol-repl.github.io/COSMol-viewer">
|
|
11
|
+
<img src="https://img.shields.io/badge/docs-latest-blue.svg" alt="Documentation Status"/>
|
|
12
|
+
</a>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
**COSMol-viewer** is a high-performance molecular visualization library, written in **Rust** and powered by **WebGPU**, designed for seamless integration into **Python** workflows.
|
|
16
|
+
|
|
17
|
+
- ⚡ **High-speed rendering** — GPU-accelerated performance at native speed
|
|
18
|
+
- 🧬 **Flexible input** — Load structures from `.sdf`, `.pdb`, or dynamically generated coordinates
|
|
19
|
+
- 📓 **Notebook-ready** — Fully compatible with Jupyter and Google Colab, ideal for teaching, research, and interactive demos
|
|
20
|
+
- 🔁 **Dynamic visualization** — Update molecular structures on-the-fly or play smooth preloaded animations
|
|
21
|
+
- 🎨 **Customizable** — Fine-grained control of rendering styles, camera, and scene parameters
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pip install cosmol-viewer
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
37
|
+
|
|
38
|
+
# === Step 1: Load and render a molecule ===
|
|
39
|
+
with open("molecule.sdf", "r") as f:
|
|
40
|
+
sdf = f.read()
|
|
41
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
42
|
+
|
|
43
|
+
scene = Scene()
|
|
44
|
+
scene.scale(0.1)
|
|
45
|
+
scene.add_shape(mol, "mol")
|
|
46
|
+
|
|
47
|
+
viewer = Viewer.render(scene, width=600, height=400) # Launch viewer
|
|
48
|
+
|
|
49
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
50
|
+
_ = input() # Keep the viewer open until you decide to close
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Animation Modes
|
|
56
|
+
|
|
57
|
+
COSMol-viewer supports **two complementary animation workflows**, depending on whether you prefer **real-time updates** or **preloaded playback**.
|
|
58
|
+
|
|
59
|
+
### 1. Real-Time Updates (Frame-by-Frame Streaming)
|
|
60
|
+
|
|
61
|
+
Update the molecule directly inside an existing scene:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import time
|
|
65
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
66
|
+
|
|
67
|
+
scene = Scene()
|
|
68
|
+
scene.scale(0.1)
|
|
69
|
+
|
|
70
|
+
# Initial load
|
|
71
|
+
with open("frames/frame_1.sdf", "r") as f:
|
|
72
|
+
sdf = f.read()
|
|
73
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
74
|
+
scene.add_shape(mol, "mol")
|
|
75
|
+
|
|
76
|
+
viewer = Viewer.render(scene, width=600, height=400)
|
|
77
|
+
|
|
78
|
+
# Update in real time
|
|
79
|
+
for i in range(2, 10):
|
|
80
|
+
with open(f"frames/frame_{i}.sdf", "r") as f:
|
|
81
|
+
sdf = f.read()
|
|
82
|
+
updated_mol = Molecules(parse_sdf(sdf)).centered()
|
|
83
|
+
|
|
84
|
+
scene.update_shape("mol", updated_mol)
|
|
85
|
+
viewer.update(scene)
|
|
86
|
+
|
|
87
|
+
time.sleep(0.033) # ~30 FPS
|
|
88
|
+
|
|
89
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
90
|
+
_ = input()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Use cases:**
|
|
94
|
+
- Visualizing the *progress* of a simulation step-by-step
|
|
95
|
+
- Interactive experiments or streaming scenarios where frames are not known in advance
|
|
96
|
+
|
|
97
|
+
**Trade-offs:**
|
|
98
|
+
- ✅ Low memory usage — no need to preload frames
|
|
99
|
+
- ⚠️ Playback smoothness depends on computation / I/O speed → may stutter if frame generation is slow
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### 2. Preloaded Playback (One-Shot Animation) (Start from 0.1.3)
|
|
104
|
+
|
|
105
|
+
Load all frames into memory first, then play them back smoothly:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
109
|
+
|
|
110
|
+
frames = []
|
|
111
|
+
interval = 0.033 # ~30 FPS
|
|
112
|
+
|
|
113
|
+
# Preload all frames
|
|
114
|
+
for i in range(1, 10):
|
|
115
|
+
with open(f"frames/frame_{i}.sdf", "r") as f:
|
|
116
|
+
sdf = f.read()
|
|
117
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
118
|
+
|
|
119
|
+
scene = Scene()
|
|
120
|
+
scene.scale(0.1)
|
|
121
|
+
scene.add_shape(mol, "mol")
|
|
122
|
+
frames.append(scene)
|
|
123
|
+
|
|
124
|
+
# Playback once
|
|
125
|
+
Viewer.play(frames, interval=interval, loops=1, width=600, height=400)
|
|
126
|
+
|
|
127
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
128
|
+
_ = input()
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Use cases:**
|
|
132
|
+
- Smooth, stable playback for presentations or teaching
|
|
133
|
+
- Demonstrating precomputed trajectories (e.g., molecular dynamics snapshots)
|
|
134
|
+
|
|
135
|
+
**Trade-offs:**
|
|
136
|
+
- ✅ Very smooth playback, independent of computation speed
|
|
137
|
+
- ⚠️ Requires preloading all frames → higher memory usage
|
|
138
|
+
- ⚠️ Longer initial load time for large trajectories
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Choosing the Right Mode
|
|
143
|
+
|
|
144
|
+
- ✅ Use **real-time updates** if your frames are generated on-the-fly or memory is limited
|
|
145
|
+
- ✅ Use **preloaded playback** if you want guaranteed smooth animations and can preload your trajectory
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Exiting the Viewer
|
|
150
|
+
|
|
151
|
+
> **Important:** The viewer is bound to the Python process.
|
|
152
|
+
> When your script finishes, the rendering window will close automatically.
|
|
153
|
+
|
|
154
|
+
To keep the visualization alive until you are ready to exit, always add:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
158
|
+
_ = input()
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
This ensures:
|
|
162
|
+
- The window stays open for inspection
|
|
163
|
+
- The user decides when to end visualization
|
|
164
|
+
- Prevents premature termination at the end of the script
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Documentation
|
|
169
|
+
|
|
170
|
+
For API reference and advanced usage, please see the [latest documentation](https://cosmol-repl.github.io/COSMol-viewer).
|
|
@@ -329,9 +329,10 @@ impl Shader {
|
|
|
329
329
|
gl.enable(glow::CULL_FACE);
|
|
330
330
|
gl.cull_face(glow::BACK);
|
|
331
331
|
gl.front_face(glow::CCW);
|
|
332
|
-
|
|
332
|
+
|
|
333
333
|
gl.enable(glow::DEPTH_TEST);
|
|
334
334
|
gl.depth_func(glow::LEQUAL);
|
|
335
|
+
gl.enable(glow::MULTISAMPLE); // 开启多重采样
|
|
335
336
|
|
|
336
337
|
gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
|
|
337
338
|
|
|
@@ -120,11 +120,6 @@ impl Sphere {
|
|
|
120
120
|
self
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
// pub fn clickable(mut self, val: bool) -> Self {
|
|
124
|
-
// self.interaction.clickable = val;
|
|
125
|
-
// self
|
|
126
|
-
// }
|
|
127
|
-
|
|
128
123
|
pub fn to_mesh(&self, scale: f32) -> MeshData {
|
|
129
124
|
let template = get_or_generate_sphere_mesh_template(self.quality);
|
|
130
125
|
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# COSMol-viewer
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
<a href="https://crates.io/crates/cosmol_viewer">
|
|
5
|
+
<img src="https://img.shields.io/crates/v/cosmol_viewer.svg" alt="crates.io Latest Release"/>
|
|
6
|
+
</a>
|
|
7
|
+
<a href="https://pypi.org/project/cosmol_viewer/">
|
|
8
|
+
<img src="https://img.shields.io/pypi/v/cosmol_viewer.svg" alt="PyPi Latest Release"/>
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://cosmol-repl.github.io/COSMol-viewer">
|
|
11
|
+
<img src="https://img.shields.io/badge/docs-latest-blue.svg" alt="Documentation Status"/>
|
|
12
|
+
</a>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
**COSMol-viewer** is a high-performance molecular visualization library, written in **Rust** and powered by **WebGPU**, designed for seamless integration into **Python** workflows.
|
|
16
|
+
|
|
17
|
+
- ⚡ **High-speed rendering** — GPU-accelerated performance at native speed
|
|
18
|
+
- 🧬 **Flexible input** — Load structures from `.sdf`, `.pdb`, or dynamically generated coordinates
|
|
19
|
+
- 📓 **Notebook-ready** — Fully compatible with Jupyter and Google Colab, ideal for teaching, research, and interactive demos
|
|
20
|
+
- 🔁 **Dynamic visualization** — Update molecular structures on-the-fly or play smooth preloaded animations
|
|
21
|
+
- 🎨 **Customizable** — Fine-grained control of rendering styles, camera, and scene parameters
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pip install cosmol-viewer
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
37
|
+
|
|
38
|
+
# === Step 1: Load and render a molecule ===
|
|
39
|
+
with open("molecule.sdf", "r") as f:
|
|
40
|
+
sdf = f.read()
|
|
41
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
42
|
+
|
|
43
|
+
scene = Scene()
|
|
44
|
+
scene.scale(0.1)
|
|
45
|
+
scene.add_shape(mol, "mol")
|
|
46
|
+
|
|
47
|
+
viewer = Viewer.render(scene, width=600, height=400) # Launch viewer
|
|
48
|
+
|
|
49
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
50
|
+
_ = input() # Keep the viewer open until you decide to close
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Animation Modes
|
|
56
|
+
|
|
57
|
+
COSMol-viewer supports **two complementary animation workflows**, depending on whether you prefer **real-time updates** or **preloaded playback**.
|
|
58
|
+
|
|
59
|
+
### 1. Real-Time Updates (Frame-by-Frame Streaming)
|
|
60
|
+
|
|
61
|
+
Update the molecule directly inside an existing scene:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import time
|
|
65
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
66
|
+
|
|
67
|
+
scene = Scene()
|
|
68
|
+
scene.scale(0.1)
|
|
69
|
+
|
|
70
|
+
# Initial load
|
|
71
|
+
with open("frames/frame_1.sdf", "r") as f:
|
|
72
|
+
sdf = f.read()
|
|
73
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
74
|
+
scene.add_shape(mol, "mol")
|
|
75
|
+
|
|
76
|
+
viewer = Viewer.render(scene, width=600, height=400)
|
|
77
|
+
|
|
78
|
+
# Update in real time
|
|
79
|
+
for i in range(2, 10):
|
|
80
|
+
with open(f"frames/frame_{i}.sdf", "r") as f:
|
|
81
|
+
sdf = f.read()
|
|
82
|
+
updated_mol = Molecules(parse_sdf(sdf)).centered()
|
|
83
|
+
|
|
84
|
+
scene.update_shape("mol", updated_mol)
|
|
85
|
+
viewer.update(scene)
|
|
86
|
+
|
|
87
|
+
time.sleep(0.033) # ~30 FPS
|
|
88
|
+
|
|
89
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
90
|
+
_ = input()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Use cases:**
|
|
94
|
+
- Visualizing the *progress* of a simulation step-by-step
|
|
95
|
+
- Interactive experiments or streaming scenarios where frames are not known in advance
|
|
96
|
+
|
|
97
|
+
**Trade-offs:**
|
|
98
|
+
- ✅ Low memory usage — no need to preload frames
|
|
99
|
+
- ⚠️ Playback smoothness depends on computation / I/O speed → may stutter if frame generation is slow
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### 2. Preloaded Playback (One-Shot Animation) (Start from 0.1.3)
|
|
104
|
+
|
|
105
|
+
Load all frames into memory first, then play them back smoothly:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
109
|
+
|
|
110
|
+
frames = []
|
|
111
|
+
interval = 0.033 # ~30 FPS
|
|
112
|
+
|
|
113
|
+
# Preload all frames
|
|
114
|
+
for i in range(1, 10):
|
|
115
|
+
with open(f"frames/frame_{i}.sdf", "r") as f:
|
|
116
|
+
sdf = f.read()
|
|
117
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
118
|
+
|
|
119
|
+
scene = Scene()
|
|
120
|
+
scene.scale(0.1)
|
|
121
|
+
scene.add_shape(mol, "mol")
|
|
122
|
+
frames.append(scene)
|
|
123
|
+
|
|
124
|
+
# Playback once
|
|
125
|
+
Viewer.play(frames, interval=interval, loops=1, width=600, height=400)
|
|
126
|
+
|
|
127
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
128
|
+
_ = input()
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Use cases:**
|
|
132
|
+
- Smooth, stable playback for presentations or teaching
|
|
133
|
+
- Demonstrating precomputed trajectories (e.g., molecular dynamics snapshots)
|
|
134
|
+
|
|
135
|
+
**Trade-offs:**
|
|
136
|
+
- ✅ Very smooth playback, independent of computation speed
|
|
137
|
+
- ⚠️ Requires preloading all frames → higher memory usage
|
|
138
|
+
- ⚠️ Longer initial load time for large trajectories
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Choosing the Right Mode
|
|
143
|
+
|
|
144
|
+
- ✅ Use **real-time updates** if your frames are generated on-the-fly or memory is limited
|
|
145
|
+
- ✅ Use **preloaded playback** if you want guaranteed smooth animations and can preload your trajectory
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Exiting the Viewer
|
|
150
|
+
|
|
151
|
+
> **Important:** The viewer is bound to the Python process.
|
|
152
|
+
> When your script finishes, the rendering window will close automatically.
|
|
153
|
+
|
|
154
|
+
To keep the visualization alive until you are ready to exit, always add:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
158
|
+
_ = input()
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
This ensures:
|
|
162
|
+
- The window stays open for inspection
|
|
163
|
+
- The user decides when to end visualization
|
|
164
|
+
- Prevents premature termination at the end of the script
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Documentation
|
|
169
|
+
|
|
170
|
+
For API reference and advanced usage, please see the [latest documentation](https://cosmol-repl.github.io/COSMol-viewer).
|