Skip to content

Commit

Permalink
fix js->py translation of spherize/cylinderize, add mesh conversion t…
Browse files Browse the repository at this point in the history
…o ChimeraX
  • Loading branch information
dnanto committed Aug 19, 2024
1 parent d20235b commit 21d2dab
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
2 changes: 1 addition & 1 deletion js/democapsid.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ function sd_sphere(p, s) {
function spherize(coor, radius, sphericity) {
return coor
.uvec()
.mul(Math.abs(sd_sphere(coor, radius)) * sphericity)
.mul(sd_sphere(coor, radius) * sphericity)
.add(coor);
}

Expand Down
52 changes: 33 additions & 19 deletions py/src/democapsid/democapsid.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ def spherize(coor, verts, sphericity):
sphericity (float): The sphericity factor.
Returns:
np.array: The projected coordinate.
np.array: The spherized coordinate.
"""
return coor + uvec(coor) * (np.abs(sd_sphere(coor, np.linalg.norm(verts[6] - verts[6][2]))) * -sphericity)

Expand All @@ -490,38 +490,33 @@ def cylinderize(coor, verts, sphericity, a=5):
a (int, optional): The axial symmetry. Defaults to 5.
Returns:
np.array: The projected coordinate.
np.array: The cylinderized coordinate.
"""
r = np.linalg.norm(verts[6] - verts[6][2])
r = np.linalg.norm(verts[6] - np.array([0, 0, verts[6][2]]))
h2 = (verts[4][2] - verts[6][2]) / 2

if a == 5:
pos = np.array([0, 0, h2 - (r / 2)])
rad = verts[0][2] + (r / 2) - h2
pos = np.array([0, 0, h2 - r / 2])
rad = verts[0][2] + r / 2 - h2
elif a == 3:
p1, p2 = verts[0], verts[3]
pos = triangle_circumcircle_center(p1, p2, np.array([p2[0], -p2[1], p2[2]]))
pos = triangle_circumcircle_center(verts[0], verts[3], np.array([p2[0], -p2[1], p2[2]]))
rad = np.linalg.norm(p1 - pos)
elif a == 2:
p1 = verts[0]
pos = tetrahedron_circumsphere_center(p1, *verts[(1, 4, 5), :])
pos = tetrahedron_circumsphere_center(verts[0], *verts[(1, 4, 5), :])
rad = np.linalg.norm(p1 - pos)

pos1 = np.array([0, 0, pos[2]])
pos2 = np.array([0, 0, -pos[2]])
tmid = np.array([0, 0, h2])
bmid = np.array([0, 0, -h2])
pos1, pos2 = np.array([0, 0, pos[2]]), np.array([0, 0, -pos[2]])
tmid, bmid = np.array([0, 0, h2]), np.array([0, 0, -h2])

if h2 < coor[2]: # top cap
d = sd_sphere(coor - pos1, rad)
d = np.abs(d)
d = np.abs(sd_sphere(coor - pos1, rad))
return (d * sphericity * uvec(coor - tmid)) + coor
elif coor[2] < -h2: # bottom cap
d = sd_sphere(coor - pos2, rad)
d = np.abs(d)
d = np.abs(sd_sphere(coor - pos2, rad))
return (d * sphericity * uvec(coor - bmid)) + coor

# body cylinder
return ((r - np.linalg.norm(coor[:2])) * sphericity * uvec(coor - coor[2])) + coor
return ((r - np.linalg.norm(coor[:2])) * sphericity * uvec(coor - np.array([0, 0, coor[2]]))) + coor


def ico_coors_2(ckv, iter=100, tol=1E-15):
Expand Down Expand Up @@ -810,3 +805,22 @@ def calc_ico(ckp, lat, a=5, s=0, iter=100, tol=1E-15):
# apply transform and inflate coordinates
meshes.append([([inflater(M @ point, coors, s) for point in vertices], edges) for vertices, edges in ckm[t_idx]])
return meshes


def meshes_to_chimerax(meshes):
"""Calculate meshes compatible with ChimeraX.
Args:
meshes (list): The list of vertex-list, edge-list tuples.
Yields:
(tuple): The next tuple specifying the i-th mesh, j-th polygon, Nx3 vertex list, MX3 triangle list, and Mx1 edge mask.
"""
for i, mesh in enumerate(meshes, start=1):
for j, polygon in enumerate(mesh, start=1):
vertices, edges = polygon
vertices.append(np.mean(vertices, axis=0))
vertices = np.vstack(vertices)
triangles = np.vstack([(len(vertices) - 1, src, tar) for src, tar in edges])
edge_mask = 2 * np.ones(len(triangles)).astype(int)
yield i, j, vertices, triangles, edge_mask

0 comments on commit 21d2dab

Please sign in to comment.