cosmol-viewer 0.1.3.dev4__tar.gz → 0.1.4.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.

Potentially problematic release.


This version of cosmol-viewer might be problematic. Click here for more details.

Files changed (32) hide show
  1. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/Cargo.lock +3 -3
  2. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/Cargo.toml +3 -3
  3. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/PKG-INFO +1 -1
  4. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/parser/sdf.rs +3 -3
  5. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shapes/molecules.rs +149 -21
  6. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/pyproject.toml +1 -1
  7. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/README.md +0 -0
  8. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/Cargo.toml +0 -0
  9. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/lib.rs +0 -0
  10. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/parser/mod.rs +0 -0
  11. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/scene.rs +0 -0
  12. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/bg_fragment.glsl +0 -0
  13. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/bg_vertex.glsl +0 -0
  14. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/canvas.rs +0 -0
  15. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/fragment.glsl +0 -0
  16. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/mod.rs +0 -0
  17. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/vertex.glsl +0 -0
  18. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/vertex_sphere.glsl +0 -0
  19. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/vertex_stick.glsl +0 -0
  20. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shapes/mod.rs +0 -0
  21. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shapes/sphere.rs +0 -0
  22. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shapes/stick.rs +0 -0
  23. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/utils.rs +0 -0
  24. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/Cargo.toml +0 -0
  25. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/README.md +0 -0
  26. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/build.rs +0 -0
  27. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/cosmol_viewer.pyi +0 -0
  28. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/src/lib.rs +0 -0
  29. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/src/parser.rs +0 -0
  30. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/src/shapes.rs +0 -0
  31. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/wasm/Cargo.toml +0 -0
  32. {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/wasm/src/lib.rs +0 -0
@@ -751,7 +751,7 @@ dependencies = [
751
751
 
752
752
  [[package]]
753
753
  name = "cosmol_viewer"
754
- version = "0.1.3-nightly.4"
754
+ version = "0.1.4-nightly.1"
755
755
  dependencies = [
756
756
  "bytemuck",
757
757
  "cosmol_viewer_core",
@@ -764,7 +764,7 @@ dependencies = [
764
764
 
765
765
  [[package]]
766
766
  name = "cosmol_viewer_core"
767
- version = "0.1.3-nightly.4"
767
+ version = "0.1.4-nightly.1"
768
768
  dependencies = [
769
769
  "bytemuck",
770
770
  "eframe",
@@ -794,7 +794,7 @@ dependencies = [
794
794
 
795
795
  [[package]]
796
796
  name = "cosmol_viewer_wasm"
797
- version = "0.1.3-nightly.4"
797
+ version = "0.1.4-nightly.1"
798
798
  dependencies = [
799
799
  "base64",
800
800
  "cosmol_viewer_core",
@@ -1,6 +1,6 @@
1
1
  [workspace.package]
2
2
  edition = "2024"
3
- version = "0.1.3-nightly.4"
3
+ version = "0.1.4-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,8 +13,8 @@ resolver = "2"
13
13
  members = ["crates/python"]
14
14
 
15
15
  [workspace.dependencies]
16
- cosmol_viewer = { version = "0.1.3-nightly.4", path = "cosmol_viewer"}
17
- cosmol_viewer_core = { version = "0.1.3-nightly.4", path = "crates/core" }
16
+ cosmol_viewer = { version = "0.1.4-nightly.1", path = "cosmol_viewer"}
17
+ cosmol_viewer_core = { version = "0.1.4-nightly.1", path = "crates/core" }
18
18
 
19
19
  eframe = { version = "0.32.3", features = ["wayland","x11"] }
20
20
  pyo3 = { version = "0.26.0", features = ["extension-module", "abi3-py37"] }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cosmol-viewer
3
- Version: 0.1.3.dev4
3
+ Version: 0.1.4.dev1
4
4
  Summary: Molecular visualization tools
5
5
  Author-email: 95028 <wjt@cosmol.org>
6
6
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
@@ -9,7 +9,7 @@ pub struct Atom {
9
9
  pub index: usize,
10
10
  pub hetflag: bool,
11
11
  pub bonds: Vec<usize>,
12
- pub bond_order: Vec<f32>,
12
+ pub bond_order: Vec<usize>,
13
13
  pub properties: std::collections::HashMap<String, String>,
14
14
  }
15
15
 
@@ -105,7 +105,7 @@ fn parse_v2000(mut lines: Vec<&str>, options: &ParserOptions) -> MoleculeData {
105
105
  .parse::<usize>()
106
106
  .unwrap_or(0)
107
107
  .saturating_sub(1);
108
- let order = line[6..].trim().parse::<f32>().unwrap_or(1.0);
108
+ let order = line[6..9].trim().parse::<usize>().unwrap_or(1);
109
109
  if let (Some(f), Some(t)) = (
110
110
  serial_to_index.get(from).and_then(|x| *x),
111
111
  serial_to_index.get(to).and_then(|x| *x),
@@ -208,7 +208,7 @@ fn parse_v3000(mut lines: Vec<&str>, options: &ParserOptions) -> MoleculeData {
208
208
  if parts.len() > 3 {
209
209
  let from = parts[2].parse::<usize>().unwrap_or(0).saturating_sub(1);
210
210
  let to = parts[3].parse::<usize>().unwrap_or(0).saturating_sub(1);
211
- let order = parts[1].parse::<f32>().unwrap_or(1.0);
211
+ let order = parts[1].parse::<usize>().unwrap_or(1);
212
212
  if let (Some(f), Some(t)) = (
213
213
  serial_to_index.get(from).and_then(|x| *x),
214
214
  serial_to_index.get(to).and_then(|x| *x),
@@ -6,10 +6,7 @@ use crate::{
6
6
  parser::sdf::MoleculeData,
7
7
  scene::{InstanceGroups, SphereInstance},
8
8
  shapes::{sphere::Sphere, stick::Stick},
9
- utils::{
10
- Interaction, Interpolatable, IntoInstanceGroups, MeshData, VisualShape,
11
- VisualStyle,
12
- },
9
+ utils::{Interaction, Interpolatable, IntoInstanceGroups, MeshData, VisualShape, VisualStyle},
13
10
  };
14
11
 
15
12
  use std::{collections::HashMap, str::FromStr};
@@ -366,7 +363,8 @@ impl IntoInstanceGroups for Molecules {
366
363
  self.atom_types
367
364
  .get(i)
368
365
  .unwrap_or(&AtomType::Unknown)
369
- .radius()* 0.2,
366
+ .radius()
367
+ * 0.2,
370
368
  )
371
369
  .color(
372
370
  self.style
@@ -378,12 +376,110 @@ impl IntoInstanceGroups for Molecules {
378
376
  groups.spheres.push(sphere_instance.to_instance(scale));
379
377
  }
380
378
 
381
- for (_i, bond) in self.bonds.iter().enumerate() {
379
+ for (i, bond) in self.bonds.iter().enumerate() {
382
380
  let [a, b] = *bond;
383
381
  let pos_a = self.atoms[a as usize];
384
382
  let pos_b = self.atoms[b as usize];
385
383
 
386
- // 获取原子颜色
384
+ let bond_type = self.bond_types.get(i).unwrap_or(&BondType::SINGLE);
385
+
386
+ // 方向向量
387
+ let dir = [
388
+ pos_b[0] - pos_a[0],
389
+ pos_b[1] - pos_a[1],
390
+ pos_b[2] - pos_a[2],
391
+ ];
392
+
393
+ // 归一化方向
394
+ let norm = (dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]).sqrt();
395
+ let dir_n = [dir[0] / norm, dir[1] / norm, dir[2] / norm];
396
+
397
+ // === Step 1: 先找 A 的邻居方向(排除 B)===
398
+ let mut neighbor_dir_opt = None;
399
+ for (j, other_bond) in self.bonds.iter().enumerate() {
400
+ let [x, y] = *other_bond;
401
+ if x as usize == a as usize && y != b {
402
+ let pos_n = self.atoms[y as usize];
403
+ neighbor_dir_opt = Some([
404
+ pos_n[0] - pos_a[0],
405
+ pos_n[1] - pos_a[1],
406
+ pos_n[2] - pos_a[2],
407
+ ]);
408
+ break;
409
+ } else if y as usize == a as usize && x != b {
410
+ let pos_n = self.atoms[x as usize];
411
+ neighbor_dir_opt = Some([
412
+ pos_n[0] - pos_a[0],
413
+ pos_n[1] - pos_a[1],
414
+ pos_n[2] - pos_a[2],
415
+ ]);
416
+ break;
417
+ }
418
+ }
419
+
420
+ // ✅ 若 A 没有邻居,则去找 B 的邻居
421
+ if neighbor_dir_opt.is_none() {
422
+ for (j, other_bond) in self.bonds.iter().enumerate() {
423
+ let [x, y] = *other_bond;
424
+ if x as usize == b as usize && y != a {
425
+ let pos_n = self.atoms[y as usize];
426
+ neighbor_dir_opt = Some([
427
+ pos_n[0] - pos_b[0],
428
+ pos_n[1] - pos_b[1],
429
+ pos_n[2] - pos_b[2],
430
+ ]);
431
+ break;
432
+ } else if y as usize == b as usize && x != a {
433
+ let pos_n = self.atoms[x as usize];
434
+ neighbor_dir_opt = Some([
435
+ pos_n[0] - pos_b[0],
436
+ pos_n[1] - pos_b[1],
437
+ pos_n[2] - pos_b[2],
438
+ ]);
439
+ break;
440
+ }
441
+ }
442
+ }
443
+
444
+ // === Step 2: 计算 offset 方向 ===
445
+ let offset = if let Some(nd) = neighbor_dir_opt {
446
+ // 用邻居方向构造共面偏移
447
+ let nd_norm = (nd[0] * nd[0] + nd[1] * nd[1] + nd[2] * nd[2]).sqrt();
448
+ let nd_n = [nd[0] / nd_norm, nd[1] / nd_norm, nd[2] / nd_norm];
449
+
450
+ // 计算 nd_n 在 dir_n 方向的投影分量
451
+ let dot = nd_n[0] * dir_n[0] + nd_n[1] * dir_n[1] + nd_n[2] * dir_n[2];
452
+ let proj = [dot * dir_n[0], dot * dir_n[1], dot * dir_n[2]];
453
+
454
+ // 去掉投影分量,得到“共面但不沿键方向”的偏移矢量
455
+ [nd_n[0] - proj[0], nd_n[1] - proj[1], nd_n[2] - proj[2]]
456
+ } else {
457
+ // ✅ A 和 B 都没有邻居 → 回到默认垂直方向
458
+ let up = if dir_n[0].abs() < 0.9 {
459
+ [1.0, 0.0, 0.0]
460
+ } else {
461
+ [0.0, 1.0, 0.0]
462
+ };
463
+ [
464
+ dir_n[1] * up[2] - dir_n[2] * up[1],
465
+ dir_n[2] * up[0] - dir_n[0] * up[2],
466
+ dir_n[0] * up[1] - dir_n[1] * up[0],
467
+ ]
468
+ };
469
+
470
+ // 归一化 offset
471
+ let off_norm =
472
+ (offset[0] * offset[0] + offset[1] * offset[1] + offset[2] * offset[2]).sqrt();
473
+ let off_n = [
474
+ offset[0] / off_norm,
475
+ offset[1] / off_norm,
476
+ offset[2] / off_norm,
477
+ ];
478
+
479
+ // 偏移距离(可调)
480
+ let d = 0.22;
481
+
482
+ // 颜色和半径与原来一致
387
483
  let color_a = match self
388
484
  .atom_types
389
485
  .get(a as usize)
@@ -392,7 +488,6 @@ impl IntoInstanceGroups for Molecules {
392
488
  AtomType::C => [0.75, 0.75, 0.75],
393
489
  other => other.color(),
394
490
  };
395
-
396
491
  let color_b = match self
397
492
  .atom_types
398
493
  .get(b as usize)
@@ -402,26 +497,59 @@ impl IntoInstanceGroups for Molecules {
402
497
  other => other.color(),
403
498
  };
404
499
 
405
- // 计算中点
406
- let mid = [
407
- 0.5 * (pos_a[0] + pos_b[0]),
408
- 0.5 * (pos_a[1] + pos_b[1]),
409
- 0.5 * (pos_a[2] + pos_b[2]),
410
- ];
500
+ // 根据键类型生成多个 stick
501
+ let (num_sticks, radius) = match bond_type {
502
+ BondType::SINGLE => (1, 0.135),
503
+ BondType::DOUBLE => (2, 0.09),
504
+ BondType::TRIPLE => (3, 0.05),
505
+ _ => (1, 0.15), // aromatic等以后再处理
506
+ };
411
507
 
412
- // bond 一:A -> 中点,颜色 A
413
- let stick_a = Stick::new(pos_a, mid, 0.15)
508
+ for k in 0..num_sticks {
509
+ let offset_mul = (k as f32 - (num_sticks - 1) as f32 * 0.5) * d;
510
+
511
+ let pos_a_k = [
512
+ pos_a[0] + off_n[0] * offset_mul,
513
+ pos_a[1] + off_n[1] * offset_mul,
514
+ pos_a[2] + off_n[2] * offset_mul,
515
+ ];
516
+ let pos_b_k = [
517
+ pos_b[0] + off_n[0] * offset_mul,
518
+ pos_b[1] + off_n[1] * offset_mul,
519
+ pos_b[2] + off_n[2] * offset_mul,
520
+ ];
521
+
522
+ // A -> 中点
523
+ let stick_a = Stick::new(
524
+ pos_a_k,
525
+ [
526
+ 0.5 * (pos_a_k[0] + pos_b_k[0]),
527
+ 0.5 * (pos_a_k[1] + pos_b_k[1]),
528
+ 0.5 * (pos_a_k[2] + pos_b_k[2]),
529
+ ],
530
+ radius,
531
+ )
414
532
  .color(color_a)
415
533
  .opacity(self.style.opacity);
416
- groups.sticks.push(stick_a.to_instance(scale));
417
534
 
418
- // bond 二:B -> 中点,颜色 B
419
- let stick_b = Stick::new(pos_b, mid, 0.15)
535
+ groups.sticks.push(stick_a.to_instance(scale));
536
+
537
+ // B -> 中点
538
+ let stick_b = Stick::new(
539
+ pos_b_k,
540
+ [
541
+ 0.5 * (pos_a_k[0] + pos_b_k[0]),
542
+ 0.5 * (pos_a_k[1] + pos_b_k[1]),
543
+ 0.5 * (pos_a_k[2] + pos_b_k[2]),
544
+ ],
545
+ radius,
546
+ )
420
547
  .color(color_b)
421
548
  .opacity(self.style.opacity);
422
- groups.sticks.push(stick_b.to_instance(scale));
423
- }
424
549
 
550
+ groups.sticks.push(stick_b.to_instance(scale));
551
+ }
552
+ }
425
553
  groups
426
554
  }
427
555
  }
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cosmol-viewer"
3
- version = "0.1.3.dev4"
3
+ version = "0.1.4.dev1"
4
4
  description = "Molecular visualization tools"
5
5
  authors = [{name = "95028", email = "wjt@cosmol.org"}]
6
6
  readme = "README.md"