{
  "export_version": "0.072",
  "framed_nodes": {},
  "groups": {},
  "nodes": {
    "Note": {
      "bl_idname": "NoteNode",
      "color": [
        0.5,
        0.5,
        1.0
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        527.1719970703125,
        -100.24063110351562
      ],
      "params": {
        "show_text": 0,
        "text": "https://github.com/elfnor/conway_polyhedron_operators"
      },
      "use_custom_color": true,
      "width": 400.0
    },
    "Scripted Node Lite": {
      "bl_idname": "SvScriptNodeLite",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        1148.46533203125,
        126.76470184326172
      ],
      "params": {
        "float_list": [
          0.0,
          0.0,
          0.029999999329447746,
          0.0,
          -0.5,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0
        ],
        "inject_params": 0,
        "injected_state": 0,
        "int_list": [
          0,
          0,
          0,
          1,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0
        ],
        "script_name": "Alt_P_alike_divider.py",
        "script_str": "\"\"\"\nin   verts  v   .=[]   n=0\nin   faces  s   .=[]   n=0\nin   scale  s   .=0.0  n=0\nin   itera  s   .=1    n=0\nin   multi  s   .=-1.0   n=0\nout  overts   v\nout  ofaces   s\n\"\"\"\n\nfrom mathutils import Vector as V\nfrom mathutils.geometry import normal as nm\nimport numpy as np\n\noverts = verts\nofaces = faces\nitera = min(max(itera,1),4)\nmulti = min(max(multi,-1.0),1.0)\n\ndef iteration(vers,facs,scal):\n    overts = []\n    ofaces = []\n    for ov, of in zip(vers, facs):\n        lv = len(ov)\n        overts_ = ov\n        ofaces_ = []\n        fcs = []\n        for f in of:\n            vrts = [ov[i] for i in f]\n            norm = nm(V(ov[f[0]]),V(ov[f[1]]),V(ov[f[2]]))\n            nv  = np.array(vrts)\n            vrt  = (nv.sum(axis=0)/len(f))+np.array(norm*scal)\n            fcs = [[i,k,lv] for i,k in zip(f,f[-1:]+f[:-1])]\n            overts_.append(vrt.tolist())\n            ofaces_.extend(fcs)\n            lv += 1\n        overts.append(overts_)\n        ofaces.append(ofaces_)\n    return overts, ofaces, scale*multi\n\nfor i in range(itera):\n    overts,ofaces,scale = iteration(overts,ofaces,scale)"
      },
      "snlite_ui": [],
      "use_custom_color": true,
      "width": 140.0
    },
    "Scripted Node Lite.001": {
      "bl_idname": "SvScriptNodeLite",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        471.9244689941406,
        126.76470184326172
      ],
      "params": {
        "float_list": [
          0.6800000071525574,
          0.05000000074505806,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0
        ],
        "inject_params": 0,
        "injected_state": 0,
        "script_name": "snl_chamfer.py",
        "script_str": "\"\"\"\nin thickness        s d=0.34 n=1\nin height        s d=0.22 n=1\nin verts_in      v d=[] n=1\nin faces_in         v d=[] n=1\nout verts_out     v\nout faces_out        v \n\"\"\"\n\nfrom conway import chamfer\n\nverts_chamfer, faces_chamfer = chamfer(verts_in, faces_in, thickness, height)\n\nfaces_out.append(faces_chamfer) \nverts_out.append(verts_chamfer)  \n"
      },
      "snlite_ui": [],
      "use_custom_color": true,
      "width": 140.0
    },
    "Scripted Node Lite.002": {
      "bl_idname": "SvScriptNodeLite",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        928.46533203125,
        126.76470184326172
      ],
      "params": {
        "float_list": [
          0.029999999329447746,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0
        ],
        "inject_params": 0,
        "injected_state": 0,
        "script_name": "snl_kis.py",
        "script_str": "\"\"\"\nin height        s d=0.1 n=1\nin verts_in      v d=[] n=1\nin faces_in         v d=[] n=1\nout verts_out     v\nout faces_out        v \n\"\"\"\n\nfrom conway import kis \n\nverts_kis, faces_kis = kis(verts_in, faces_in, height)\n\nfaces_out.append(faces_kis) \nverts_out.append(verts_kis)  \n\n\n\n"
      },
      "snlite_ui": [],
      "use_custom_color": true,
      "width": 140.0
    },
    "Scripted Node Lite.003": {
      "bl_idname": "SvScriptNodeLite",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        274.3766174316406,
        126.76470184326172
      ],
      "params": {
        "custom_enum": "gyro",
        "inject_params": 0,
        "injected_state": 0,
        "script_name": "snl_conway_op.py",
        "script_str": "\"\"\"\nin verts_in      v d=[] n=1\nin faces_in         v d=[] n=1\nenum = identity kis dual ambo chamfer gyro propellor whirl \nout verts_out     v\nout faces_out        v\n\"\"\"\n\nimport conway\n\ndef ui(self, context, layout):\n    layout.prop(self, 'custom_enum', expand=False)\n\n\nif self.custom_enum == 'identity':\n    faces_op = faces_in\n    verts_op = verts_in\nelse:\n    cw_op = getattr(conway, self.custom_enum)\n    verts_op, faces_op = cw_op(verts_in, faces_in)\n\n\nfaces_out.append(faces_op) \nverts_out.append(verts_op) "
      },
      "snlite_ui": [],
      "use_custom_color": true,
      "width": 140.0
    },
    "Scripted Node Lite.004": {
      "bl_idname": "SvScriptNodeLite",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        20.103172302246094,
        126.76470184326172
      ],
      "params": {
        "custom_enum": "dodeca",
        "inject_params": 0,
        "injected_state": 0,
        "script_name": "snl_plato.py",
        "script_str": "\"\"\"\nin dummy  s\nenum = tetra octa cube dodeca icosa\nout vertices      v\nout faces         v \n\"\"\"\n\nplato = {'tetra': \"4\",'cube': '6', 'octa': '8', 'dodeca': '12', 'icosa': '20'}\n\nfrom add_mesh_extra_objects.add_mesh_solid import source\n\ndef ui(self, context, layout):\n    layout.prop(self, 'custom_enum', expand=False)\n\n\nvectors, faces = source(plato[self.custom_enum])\nvertices = [list(v) for v in vectors]\n   \n# match  nesting of other Sverchok generators\nvertices = [vertices]\nfaces = [faces]"
      },
      "snlite_ui": [],
      "use_custom_color": true,
      "width": 140.0
    },
    "Scripted Node Lite.005": {
      "bl_idname": "SvScriptNodeLite",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        695.9929809570312,
        133.01229858398438
      ],
      "params": {
        "custom_enum": "whirl",
        "inject_params": 0,
        "injected_state": 0,
        "script_name": "snl_conway_op.py",
        "script_str": "\"\"\"\nin verts_in      v d=[] n=1\nin faces_in         v d=[] n=1\nenum = identity kis dual ambo chamfer gyro propellor whirl \nout verts_out     v\nout faces_out        v\n\"\"\"\n\nimport conway\n\ndef ui(self, context, layout):\n    layout.prop(self, 'custom_enum', expand=False)\n\n\nif self.custom_enum == 'identity':\n    faces_op = faces_in\n    verts_op = verts_in\nelse:\n    cw_op = getattr(conway, self.custom_enum)\n    verts_op, faces_op = cw_op(verts_in, faces_in)\n\n\nfaces_out.append(faces_op) \nverts_out.append(verts_op) "
      },
      "snlite_ui": [],
      "use_custom_color": true,
      "width": 140.0
    },
    "Scripted Node Lite.006": {
      "bl_idname": "SvScriptNodeLite",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": true,
      "label": "",
      "location": [
        118.40363311767578,
        -64.541259765625
      ],
      "params": {
        "custom_enum": "A",
        "float_list": [
          0.3400000035762787,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0
        ],
        "inject_params": 0,
        "injected_state": 0,
        "script_name": "canon.py",
        "script_str": "\"\"\"\nin a       s d=0.34 n=1\nout a      s\n\"\"\"\n\n\"\"\"\nfunctions used in 'canonicalization' of polyhedra\n\nThis canonical form of a polyhedron is where the verticies of the polyhedron are positioned such that:\n    all the edges are tangent to the unit sphere,\n    the origin is the center of gravity of the points at which the edges touch the sphere,\n    the faces are flat (i.e. the vertices of each face lie in some plane), but are not necessarily regular.\n\"\"\"\n\nimport copy\nimport mathutils\nimport conway as cw\n\n\ndef tangentify(verts, faces, scale):\n    \"\"\"\n    For each edge, find the closest point to the origin\n    move the two end points of the edge so the edge is closer to tangent to\n    the unit sphere\n    \"\"\"\n    verts_tang = copy.deepcopy(verts)\n    for face in faces:\n        for v1, v2 in zip(face, face[1:] + face[:1]):\n            if v1 < v2:\n                va_xyz, s = mathutils.geometry.intersect_point_line(\n                    mathutils.Vector(),\n                    verts[v1], verts[v2])\n                c = scale * 0.5 * (1 - va_xyz.length) * va_xyz\n\n                verts_tang[v1] = verts_tang[v1] + c\n                verts_tang[v2] = verts_tang[v2] + c\n\n    return verts_tang\n\n\ndef recenter(verts, faces):\n    \"\"\"\n    move verts so center of tangent points is at origin\n    \"\"\"\n    nedges = 0\n    vsum = mathutils.Vector()\n    for face in faces:\n        for v1, v2 in zip(face, face[1:] + face[:1]):\n            if v1 < v2:\n                nedges += 1\n                va_xyz, s = mathutils.geometry.intersect_point_line(\n                    mathutils.Vector(),\n                    verts[v1], verts[v2])\n                vsum = vsum + va_xyz\n\n    center_xyz = vsum/nedges\n    verts_cent = [v_xyz - center_xyz for v_xyz in verts]\n    return verts_cent\n\n\ndef planarize(verts, faces, scale):\n    \"\"\"\n    move verts in each face closer to a plane defined by the face normal\n    direction and the face centroid\n    \"\"\"\n    verts_plane = copy.deepcopy(verts)\n    for face in faces:\n        center_xyz = mathutils.Vector(cw.face_center(verts, face))\n        norm = cw.face_normal(verts, face)\n        for v1 in face:\n            r1 = center_xyz - verts[v1]\n            r2 = scale * norm\n            r4 = r2.dot(r1) * norm\n            verts_plane[v1] = verts_plane[v1] + r4\n    return verts_plane\n\ndef canonize(verts_new, faces_in, iterations, scale_factor):\n    \"\"\"\n    repeat tangentify, recenter, planarize for iterations\n    \"\"\"\n    for i in range(iterations):\n        verts_old = copy.deepcopy(verts_new)\n        verts_new = tangentify(verts_new, faces_in, scale_factor)\n        verts_new = recenter(verts_new, faces_in)\n        verts_new = planarize(verts_new, faces_in, scale_factor)\n        max_change = max([abs((verts_old[v1] - verts_new[v1]).length)\n                          for v1, v_xyz in enumerate(verts_old)])\n        if max_change < 1e-8:\n            break\n    return verts_new"
      },
      "snlite_ui": [],
      "use_custom_color": true,
      "width": 140.0
    },
    "Scripted Node Lite.007": {
      "bl_idname": "SvScriptNodeLite",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": true,
      "label": "",
      "location": [
        118.90845489501953,
        -99.36140441894531
      ],
      "params": {
        "custom_enum": "A",
        "float_list": [
          0.3400000035762787,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0,
          0.0
        ],
        "inject_params": 0,
        "injected_state": 0,
        "script_name": "conway.py",
        "script_str": "\"\"\"\nin a       s d=0.34 n=1\nout a      s\n\"\"\"\n\"\"\"\nfunctions to implement conway-hart operators on polyhedron\ndesigned for use with Svercook scripted nodes\nIs standalone apart from dependency on Blender mathutils module for vector functions\n\n\"\"\"\nfrom collections import defaultdict\nimport mathutils\n\n\n# ---- Face and edge functions\n\ndef face_center(verts, face, height=None):\n    \"\"\"\n    find the center of a face\n    inputs:\n    verts: list of x, y, z coords of verticies\n    face:  list of indcies of verts in face\n    height: height of returned vertex above plane of face.\n    output:\n    center: center x, y, z coords as list\n    \"\"\"\n    verts_xyz = [verts[v_i] for v_i in face]\n    x_co, y_co, z_co = zip(*verts_xyz)\n    center = sum(x_co)/len(x_co), sum(y_co)/len(y_co), sum(z_co)/len(z_co)\n    if height:\n        center = mathutils.Vector(center)\n        norm = mathutils.geometry.normal(verts_xyz)\n        center = list(center + norm * height)\n    return center\n\n\ndef face_normal(verts, face):\n    \"\"\"\n    normal direction of face as mathutils Vector\n    \"\"\"\n    norm = mathutils.geometry.normal([verts[v_i] for v_i in face])\n    return norm\n\n\ndef edge_center(verts, edge):\n    \"\"\"\n    find the middle point on edge\n    \"\"\"\n    v1_xyz = mathutils.Vector(verts[edge[0]])\n    v2_xyz = mathutils.Vector(verts[edge[1]])\n    va_xyz = v1_xyz + (v2_xyz - v1_xyz)/2.0\n    return list(va_xyz)\n\n\ndef edge_third(verts, edge):\n    \"\"\"\n    find a point one third along edge\n    \"\"\"\n    v1_xyz = mathutils.Vector(verts[edge[0]])\n    v2_xyz = mathutils.Vector(verts[edge[1]])\n    va_xyz = v1_xyz + (v2_xyz - v1_xyz)/3.0\n    return list(va_xyz)\n\n\ndef tangent_point(verts, edge):\n    \"\"\"\n    find the closest point to the origin on edge\n    \"\"\"\n    v1_xyz = mathutils.Vector(verts[edge[0]])\n    v2_xyz = mathutils.Vector(verts[edge[1]])\n    va_xyz, _s = mathutils.geometry.intersect_point_line(mathutils.Vector(),\n                                                         v1_xyz, v2_xyz)\n    return list(va_xyz)\n\n\n# ---- flag tag functions\n\ndef faces_to_flags(faces, face_tags=None, edge_key=False):\n    \"\"\"\n    takes a list of faces, where each face is given as a list of verts in CCW order\n    and returns flags, verts_tags\n\n    face_tags is an optional list of tags for the faces\n\n    flags is a dict where the\n    key  face tag + vert tag\n    value  (face tag, vert tag, tag of next CCW vert in the face)\n\n    if edge_key == True\n    the key for flags is\n    key : v1_t + v2_t\n    this allows faces opposing across an edge to be found easily\n\n\n    vert_tags\n    key   vert tag\n    value index of vert\n\n\n    This makes looking up the next vertex quick. There will be two flags for every edge in\n    the mesh represented by faces.\n    \"\"\"\n    flags = {}\n    vert_tags = {}\n    for face_i, face in enumerate(faces):\n        try:\n            face_t = face_tags[face_i]\n        except (TypeError, IndexError):\n            face_t = 'f{}'.format(face_i)\n        for v1, v2 in zip(face, face[1:] + face[:1]):\n            v1_t = 'v{}'.format(v1)\n            v2_t = 'v{}'.format(v2)\n            if edge_key:\n                flags[v1_t + v2_t] = [face_t, v1_t, v2_t]\n            else:\n                # default\n                flags[face_t + v1_t] = [face_t, v1_t, v2_t]\n            vert_tags[v1_t] = v1\n    return flags, vert_tags\n\n\ndef flags_to_faces(flags, vert_tags):\n    \"\"\"\n    flags is a dict where the\n    key  face tag + vert tag\n    value  (face tag, vert tag, tag of next CCW vert in the face)\n\n    vert_tags\n    key   vert tag\n    value index of vert\n\n    returns a list of faces, where each face is\n    given as a list of vert indices in CCW order\n    and a list of face tags in the same order as faces\n    \"\"\"\n    face_count = defaultdict(int)\n    vert_one = {}\n    faces = []\n    face_tags = []  # list of face_t in the same order as faces\n\n    # find how many verts in each face, and  keep one vert from each face\n    for flag in flags.values():\n        face_count[flag[0]] += 1\n        vert_one[flag[0]] = flag[1]\n\n    for face_t, vert_count in face_count.items():\n        face_vt = [vert_one[face_t]]\n        while len(face_vt) < vert_count:\n            v1_t = face_vt[-1]\n            # find the flag (face_t, v1_t, v2_t)\n            v2_t = flags[face_t + v1_t][2]\n            face_vt.append(v2_t)\n        face_ccw = [vert_tags[v_t] for v_t in face_vt]\n        faces.append(face_ccw)\n        face_tags.append(face_t)\n    return faces, face_tags\n\n\ndef face_vt_to_flags(face_t, face_vt):\n    \"\"\"\n    returns the flags for a complete new face\n    input:\n        face_t: string tag to name face\n        face_vt: list of vertex tags\n    output\n        flags: flags is a dict where the\n                key  face tag + vert tag\n                value  (face tag, vert tag, tag of next CCW vert in the face)\n    \"\"\"\n    flags = {}\n    for v1_t, v2_t in zip(face_vt, face_vt[1:] + face_vt[:1]):\n        flags[face_t + v1_t] = [face_t, v1_t, v2_t]\n\n    return flags\n\n\n# ---- Conway Operators\n\ndef kis(verts_in, faces_in, height=0.0):\n    \"\"\"\n    each n-face is divided into n triangles which extend to the face centroid\n    existing vertices retained\n    equivalent to Blender poke operator\n    \"\"\"\n    flags_kis = {}\n    verts_kis = verts_in[:]\n    vert_tags = {'v{}'.format(i): i for i, v in enumerate(verts_kis)}\n\n    for face_i, face in enumerate(faces_in):\n        verts_kis.append(face_center(verts_in, face, height))\n        vert_tags['vf{}'.format(face_i)] = len(verts_kis) - 1\n        for v1, v2 in zip(face, face[1:] + face[:1]):\n            # 3 flags for the face\n            f3_t = 'f{}:{}'.format(face_i, v1)\n            va_t = 'v{}'.format(v1)\n            vb_t = 'v{}'.format(v2)\n            vc_t = 'vf{}'.format(face_i)\n            flags_new = face_vt_to_flags(f3_t, [va_t, vb_t, vc_t])\n            flags_kis.update(flags_new)\n\n    faces_kis = flags_to_faces(flags_kis, vert_tags)[0]\n    return verts_kis, faces_kis\n\n\ndef dual(verts_in, faces_in):\n    \"\"\"\n    faces become vertices, vertices become faces\n    The dual of a polyhedron is another mesh wherein:\n    - every face in the original becomes a vertex in the dual\n    - every vertex in the original becomes a face in the dual\n    v = f, e = e, f = v\n\n    \"\"\"\n    verts_dual = []\n    verts_out_tags = {}\n    flags_dual = {}\n\n    # make edge indexed flags for old mesh\n    flags_in, verts_in_tags = faces_to_flags(faces_in, edge_key=True)\n\n    for face_i, face in enumerate(faces_in):\n        verts_dual.append(face_center(verts_in, face))\n        verts_out_tags['vf{}'.format(face_i)] = len(verts_dual) - 1\n\n        for v1, v2 in zip(face, face[1:] + face[:1]):\n            va_t = 'vf{}'.format(face_i)\n            # find the tag of the face across edge (v1, v2) from face_i\n            edge_key = 'v{}v{}'.format(v2, v1)\n            fopp_t = flags_in[edge_key][0]\n            vb_t = fopp_t.replace('f', 'vf')\n\n            # make one new flag for each old half-edge\n            fdual_t = 'fv{}'.format(v1)\n            flags_dual[fdual_t + vb_t] = [fdual_t, vb_t, va_t]\n\n    faces, face_tags = flags_to_faces(flags_dual, verts_out_tags)\n\n    # sort outgoing faces to be in same order as incoming verts\n    face_dict = {int(k[2:]): v for k, v in zip(face_tags, faces)}\n    faces_sorted = [face_dict[i] for i in sorted(face_dict)]\n\n    return verts_dual, faces_sorted\n\n\ndef ambo(verts_in, faces_in):\n    \"\"\"\n    New vertices are added mid-edges, while old vertices are removed.\n    results in a face per original face and a face per original vertex\n    This is full truncation to the mid-point of the edge\n    equivalent to the bevel operator, vertex only, percent, amount = 50 2e\n    \"\"\"\n    verts_ambo = []  # new verts at the centre of old edges\n    vert_tags = {}\n    flags_ambo = {}\n\n    for face_i, face in enumerate(faces_in):\n        for v1, v2, v3 in zip(face, face[1:] + face[:1], face[2:] + face[:2]):\n            va_t = 'v{}:{}'.format(*sorted((v1, v2)))\n            if va_t not in vert_tags:\n                verts_ambo.append(edge_center(verts_in, (v1, v2)))\n                vert_tags[va_t] = len(verts_ambo) - 1\n\n            vb_t = 'v{}:{}'.format(*sorted((v2, v3)))\n            # add two flags along the edge (va, vb)\n            fcenter_t = 'f{}'.format(face_i)\n            flags_ambo[fcenter_t + va_t] = [fcenter_t, va_t, vb_t]\n            fvert_t = 'fv{}'.format(v2)\n            flags_ambo[fvert_t + vb_t] = [fvert_t, vb_t, va_t]\n\n    faces_ambo = flags_to_faces(flags_ambo, vert_tags)[0]\n    return verts_ambo, faces_ambo\n\n\ndef chamfer(verts_in, faces_in, thickness=0.1, height=0.1):\n    \"\"\"\n    An edge-truncation.\n    New hexagonal faces are added in place of edges.\n     v = v + 2e, e = 4e, f = f + e\n    \"\"\"\n    flags_chamf = {}\n\n    verts_chamf = verts_in[:]\n    vert_tags = {'v{}'.format(i): i for i, v in enumerate(verts_chamf)}\n\n    for face_i, face in enumerate(faces_in):\n        for v1, v2 in zip(face, face[1:] + face[:1]):\n            center = mathutils.Vector(face_center(verts_chamf, face))\n            v2_xyz = mathutils.Vector(verts_chamf[v2])\n\n            face_norm = mathutils.geometry.normal([verts_chamf[v_i] for v_i in face])\n            vb_xyz = v2_xyz + (center - v2_xyz) * thickness + face_norm * height\n\n            verts_chamf.append(list(vb_xyz))\n            vb_t = 'v{}f{}'.format(v2, face_i)\n            vert_tags[vb_t] = len(verts_chamf) - 1\n\n            # add 4 flags\n            face_chamf_t = 'f{}:{}'.format(*sorted((v1, v2)))\n            face_t = 'f{}'.format(face_i)\n            va_t = 'v{}'.format(v2)\n            vc_t = 'v{}f{}'.format(v1, face_i)\n            vd_t = 'v{}'.format(v1)\n\n            flags_chamf[face_chamf_t + va_t] = [face_chamf_t, va_t, vb_t]\n            flags_chamf[face_chamf_t + vb_t] = [face_chamf_t, vb_t, vc_t]\n            flags_chamf[face_chamf_t + vc_t] = [face_chamf_t, vc_t, vd_t]\n\n            flags_chamf[face_t + vc_t] = [face_t, vc_t, vb_t]\n\n    faces_chamf = flags_to_faces(flags_chamf, vert_tags)[0]\n    return verts_chamf, faces_chamf\n\n\ndef gyro(verts_in, faces_in):\n    \"\"\"\n    gyro is like kis but with the new edges connecting the face centers to the 1/3 points\n    on the edges rather than the vertices.\n    v = v + 2e +  f,  f = 2e ,  e = 5e\n    \"\"\"\n    verts_gyro = verts_in[:]\n    vert_tags = {'v{}'.format(i): i for i, v in enumerate(verts_gyro)}\n\n    flags_gyro = {}\n\n    for face_i, face in enumerate(faces_in):\n        verts_gyro.append(face_center(verts_in, face))\n        vert_tags['vf{}'.format(face_i)] = len(verts_gyro) - 1\n\n        for v1, v2, v3 in zip(face, face[1:] + face[:1], face[2:] + face[:2]):\n            va_t = 'v{}:{}'.format(v1, v2)\n            verts_gyro.append(edge_third(verts_in, (v1, v2)))\n            vert_tags[va_t] = len(verts_gyro) - 1\n\n            # do five flags for the new face that shares two egdes with edge v1, v2\n            face_t = 'f{}:{}'.format(face_i, v2)\n            vb_t = 'v{}:{}'.format(v2, v1)\n            vc_t = 'v{}'.format(v2)\n            vd_t = 'v{}:{}'.format(v2, v3)\n            ve_t = 'vf{}'.format(face_i)\n\n            flags_new = face_vt_to_flags(face_t, [va_t, vb_t, vc_t, vd_t, ve_t])\n            flags_gyro.update(flags_new)\n\n    faces_gyro = flags_to_faces(flags_gyro, vert_tags)[0]\n    return verts_gyro, faces_gyro\n\n\ndef propellor(verts_in, faces_in):\n    \"\"\"\n    builds a new 'skew face' by making new points along edges, 1/3rd the distance from v1->v2,\n    then connecting these into a new inset face.  This breaks rotational symmetry about the\n    faces, whirling them into gyres\n    v = v +2e, e = 5e, f = f + 2e\n    \"\"\"\n    verts_prop = verts_in[:]\n    vert_tags = {'v' + str(i): i for i, v in enumerate(verts_prop)}\n\n    flags_prop = {}\n\n    for face_i, face in enumerate(faces_in):\n        for v1, v2, v3 in zip(face, face[1:] + face[:1], face[2:] + face[:2]):\n            va_t = 'v{}:{}'.format(v1, v2)\n            verts_prop.append(edge_third(verts_in, (v1, v2)))\n            vert_tags[va_t] = len(verts_prop) - 1\n\n            face_t = 'f{}'.format(face_i)\n            f4_t = 'f{}:{}'.format(face_i, v2)\n            vb_t = 'v{}:{}'.format(v2, v1)\n            vc_t = 'v{}'.format(v2)\n            vd_t = 'v{}:{}'.format(v2, v3)\n\n            # add flag for centre face\n            flags_prop[face_t + va_t] = [face_t, va_t, vd_t]\n            # add 4 sided face which has two verts (vA, vB)  along edge v1, v2\n            flags_new = face_vt_to_flags(f4_t, [va_t, vb_t, vc_t, vd_t])\n            flags_prop.update(flags_new)\n\n    faces_prop = flags_to_faces(flags_prop, vert_tags)[0]\n    return verts_prop, faces_prop\n\n\ndef whirl(verts_in, faces_in):\n    \"\"\"\n    gyro followed by truncation of vertices centered at original faces.\n    This create 2 new hexagons for every original edge,\n    v = v+4e, e=7e, f=f+2e\n    \"\"\"\n    verts_whirl = verts_in[:]\n    vert_tags = {'v{}'.format(i): i for i, v in enumerate(verts_whirl)}\n\n    flags_whirl = {}\n\n    for face_i, face in enumerate(faces_in):\n\n        for v1, v2, v3 in zip(face, face[1:] + face[:1], face[2:] + face[:2]):\n            # new vert on face\n            va_t = 'vf{}:{}'.format(face_i, v1)\n            center = mathutils.Vector(face_center(verts_whirl, face))\n            v1_xyz = mathutils.Vector(verts_whirl[v1])\n            va_xyz = v1_xyz + (center - v1_xyz)/2.0\n            verts_whirl.append(list(va_xyz))\n            vert_tags[va_t] = len(verts_whirl) - 1\n\n            # new vert on edge\n            vb_t = 'v{}:{}'.format(v1, v2)\n            verts_whirl.append(edge_third(verts_in, (v1, v2)))\n            vert_tags[vb_t] = len(verts_whirl) - 1\n\n            # 7 flags\n            f6_t = 'f{}:{}'.format(face_i, v2)\n\n            vc_t = 'v{}:{}'.format(v2, v1)\n            vd_t = 'v{}'.format(v2)\n            ve_t = 'v{}:{}'.format(v2, v3)\n            vf_t = 'vf{}:{}'.format(face_i, v2)\n\n            flags_new = face_vt_to_flags(f6_t,\n                                         [va_t, vb_t, vc_t, vd_t, ve_t, vf_t])\n            flags_whirl.update(flags_new)\n\n            face_t = 'f{}'.format(face_i)\n            flags_whirl[face_t + va_t] = [face_t, va_t, vf_t]\n\n    faces_whirl = flags_to_faces(flags_whirl, vert_tags)[0]\n    return verts_whirl, faces_whirl\n"
      },
      "snlite_ui": [],
      "use_custom_color": true,
      "width": 140.0
    },
    "Viewer Draw.004": {
      "bl_idname": "ViewerNode2",
      "color": [
        0.6284880042076111,
        0.931007981300354,
        1.0
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        1468.513671875,
        126.76470184326172
      ],
      "params": {
        "activate": 1,
        "display_edges": 0,
        "display_verts": 0,
        "face_colors": [
          0.8990002274513245,
          0.2913559377193451,
          0.10470365732908249
        ],
        "shading": 1
      },
      "use_custom_color": true,
      "width": 140.0
    }
  },
  "update_lists": [
    [
      "Scripted Node Lite.004",
      0,
      "Scripted Node Lite.003",
      0
    ],
    [
      "Scripted Node Lite.004",
      1,
      "Scripted Node Lite.003",
      1
    ],
    [
      "Scripted Node Lite.003",
      0,
      "Scripted Node Lite.001",
      2
    ],
    [
      "Scripted Node Lite.003",
      1,
      "Scripted Node Lite.001",
      3
    ],
    [
      "Scripted Node Lite.001",
      0,
      "Scripted Node Lite.005",
      0
    ],
    [
      "Scripted Node Lite.001",
      1,
      "Scripted Node Lite.005",
      1
    ],
    [
      "Scripted Node Lite.005",
      0,
      "Scripted Node Lite.002",
      1
    ],
    [
      "Scripted Node Lite.005",
      1,
      "Scripted Node Lite.002",
      2
    ],
    [
      "Scripted Node Lite.002",
      0,
      "Scripted Node Lite",
      0
    ],
    [
      "Scripted Node Lite.002",
      1,
      "Scripted Node Lite",
      1
    ],
    [
      "Scripted Node Lite",
      0,
      "Viewer Draw.004",
      0
    ],
    [
      "Scripted Node Lite",
      1,
      "Viewer Draw.004",
      1
    ]
  ]
}