diff --git a/blender/blendocapsid/operators.py b/blender/blendocapsid/operators.py index bf6e5dc..edffab1 100644 --- a/blender/blendocapsid/operators.py +++ b/blender/blendocapsid/operators.py @@ -6,18 +6,43 @@ class CapsidMesh(bpy.types.Operator): bl_idname = "object.add_mesh" bl_label = "Add Capsid Mesh" bl_options = {"REGISTER", "UNDO"} + axis_items = [ + ("2", "2", "two-fold axial symmetry", 2), + ("3", "3", "three-fold axial symmetry", 3), + ("5", "5", "five-fold axial symmetry", 5) + ] + tile_items = [ + (key, key, f"{key} lattice", idx) + for idx, key in enumerate((pfx + ele for pfx in ("", "dual") for ele in ("hex", "trihex", "snubhex", "rhombitrihex")), start=1) + ] + mode_items = [ + ("ico", "ico", "render icosahedral mesh", 1), + ("tri", "tri", "render triangular Caspar-Klug meshes", 2) + ] + + h: bpy.props.IntProperty(name="h", description="the h Caspar-Klug parameter", default=1, min=0) + k: bpy.props.IntProperty(name="k", description="the k Caspar-Klug parameter", default=0, min=0) + H: bpy.props.IntProperty(name="H", description="the H Caspar-Klug parameter", default=1, min=0) + K: bpy.props.IntProperty(name="K", description="the K Caspar-Klug parameter", default=0, min=0) + a: bpy.props.EnumProperty(name="a", description="the axial symmetry", items=axis_items, default=axis_items[2][3]) + R: bpy.props.FloatProperty(name="R", description="the hexagonal lattice unit circumradius", default=1, min=0) + t: bpy.props.EnumProperty(name="t", description="the hexagonal lattice unit tile", items=tile_items, default=tile_items[0][3]) + s: bpy.props.FloatProperty(name="s", description="the sphericity value", default=0, min=-1, max=1) + m: bpy.props.EnumProperty(name="mode", description="the render mode", items=mode_items, default=mode_items[0][3]) + iter: bpy.props.IntProperty(name="iter", description="the iteration number for numerical methods", default=100, min=1) + tol: bpy.props.FloatProperty(name="tol", description="the machine epsilon for numerical methods", default=1E-15, min=0) def execute(self, context): from blendocapsid.modules.democapsid.democapsid import (calc_ckm, calc_ico, calc_lattice) - - m, a, s = "ico", 5, 0 - ckp = (3, 1, 4, 2) - lat = calc_lattice("hex", 1) + + m, a, s = self.m, int(self.a), self.s + ckp = (self.h, self.k, self.H, self.K) + lat = calc_lattice(self.t, self.R) if m == "ico": - meshes = calc_ico(ckp, lat, a=a, s=s) + meshes = calc_ico(ckp, lat, a=a, s=s, iter=self.iter, tol=self.tol) elif m == "tri": meshes = calc_ckm(ckp, lat) diff --git a/py/src/democapsid/cli.py b/py/src/democapsid/cli.py index 45c8b28..0483aa8 100644 --- a/py/src/democapsid/cli.py +++ b/py/src/democapsid/cli.py @@ -10,14 +10,13 @@ def parse_args(argv): for ele in "hkHK": parser.add_argument(ele, default=1, type=int, help=f"the {ele} Caspar-Klug parameter") choices = (5, 3, 2) - parser.add_argument("-a", "-axis", default=choices[0], choices=choices, type=int, help=f"the axial symmetry: {choices}") + parser.add_argument("-a", "-axis", default=choices[0], choices=choices, type=int, help="the axial symmetry") parser.add_argument("-R", "-radius", default=1, type=int, help="the hexagonal lattice unit circumradius") - choices = ("hex", "trihex", "snubhex", "rhombitrihex") - choices = (*choices, *("dual" + ele for ele in choices)) + choices = (pfx + ele for pfx in ("", "dual") for ele in ("hex", "trihex", "snubhex", "rhombitrihex")) parser.add_argument("-t", "-tile", default=choices[0], choices=choices, help="the hexagonal lattice unit tile") parser.add_argument("-s", "-sphericity", default=0, type=float, help="the sphericity value") choices = ("ico", "tri") parser.add_argument("-m", "-mode", default=choices[0], choices=choices, help="the render mode") - parser.add_argument("-iter", default=100, type=int, help="the number of iterations for numerical methods") - parser.add_argument("-tol", default=1E-15, type=float, help="the machine epsilon") + parser.add_argument("-iter", default=100, type=int, help="the iteration number for numerical methods") + parser.add_argument("-tol", default=1E-15, type=float, help="the machine epsilon for numerical methods") return parser.parse_args(argv) diff --git a/py/src/democapsid/democapsid.py b/py/src/democapsid/democapsid.py index b630d71..88e3dde 100755 --- a/py/src/democapsid/democapsid.py +++ b/py/src/democapsid/democapsid.py @@ -529,8 +529,8 @@ def ico_coors_2(ckv, iter=100, tol=1E-15): Args: ckv (list): The Casar-Klug vectors. - iter (int, optional): The number of iterations for numerical methods. Defaults to 100. - tol (float, optional): The machine epsilon. Defaults to 1E-15. + iter (int, optional): The iteration number for numerical methods. Defaults to 100. + tol (float, optional): The machine epsilon for numerical methods. Defaults to 1E-15. Returns: np.array: The array of vertex coordinates. @@ -594,8 +594,8 @@ def ico_coors_3(ckv, iter=100, tol=1E-15): Args: ckv (list): The Casar-Klug vectors. - iter (int, optional): The number of iterations for numerical methods. Defaults to 100. - tol (float, optional): The machine epsilon. Defaults to 1E-15. + iter (int, optional): The iteration number for numerical methods. Defaults to 100. + tol (float, optional): The machine epsilon for numerical methods. Defaults to 1E-15. Returns: np.array: The array of vertex coordinates. @@ -789,8 +789,8 @@ def calc_ico(ckp, lat, a=5, s=0, iter=100, tol=1E-15): lat (tuple): The lattice tuple (basis, list of unit tiler functions). a (int, optional): The axial symmetry. Defaults to 5. s (int, optional): The sphericity. Defaults to 0. - iter (int, optional): The number of iterations for numerical methods. Defaults to 100. - tol (_type_, optional): The machine epsilon. Defaults to 1E-15. + iter (int, optional): The iteration number for numerical methods. Defaults to 100. + tol (float, optional): The machine epsilon for numerical methods. Defaults to 1E-15. Returns: list: The list of meshes for each face.