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.
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/Cargo.lock +3 -3
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/Cargo.toml +3 -3
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/PKG-INFO +1 -1
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/parser/sdf.rs +3 -3
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shapes/molecules.rs +149 -21
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/pyproject.toml +1 -1
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/README.md +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/Cargo.toml +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/lib.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/parser/mod.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/scene.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/bg_fragment.glsl +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/bg_vertex.glsl +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/canvas.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/fragment.glsl +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/mod.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/vertex.glsl +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/vertex_sphere.glsl +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/vertex_stick.glsl +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shapes/mod.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shapes/sphere.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shapes/stick.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/utils.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/Cargo.toml +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/README.md +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/build.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/cosmol_viewer.pyi +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/src/lib.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/src/parser.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/python/src/shapes.rs +0 -0
- {cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/wasm/Cargo.toml +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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
|
+
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.
|
|
17
|
-
cosmol_viewer_core = { version = "0.1.
|
|
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"] }
|
|
@@ -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<
|
|
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::<
|
|
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::<
|
|
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()
|
|
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 (
|
|
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
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
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
|
-
|
|
413
|
-
|
|
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
|
-
|
|
419
|
-
|
|
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
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/bg_fragment.glsl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.dev1}/crates/core/src/shader/vertex_sphere.glsl
RENAMED
|
File without changes
|
{cosmol_viewer-0.1.3.dev4 → cosmol_viewer-0.1.4.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|