{
  "export_version": "0.072",
  "framed_nodes": {
    "A Number": "Frame.004",
    "Frame.001": "Frame",
    "Frame.002": "Frame",
    "Frame.003": "Frame",
    "Frame.004": "Frame",
    "Move": "Frame.004",
    "Move.001": "Frame.004",
    "NGon": "Frame.001",
    "Note": "Frame.004",
    "Pipe": "Frame.002",
    "Random Vector MK2": "Frame.004",
    "Scripted Node": "Frame.003",
    "Vector Noise MK2": "Frame.004",
    "Vector in": "Frame.004",
    "Vector in.001": "Frame.004",
    "Vector in.002": "Frame.002",
    "Vector in.003": "Frame.004",
    "Viewer Draw": "Frame.001",
    "Viewer Draw.001": "Frame.004",
    "Viewer Draw.002": "Frame.002"
  },
  "groups": {},
  "nodes": {
    "A Number": {
      "bl_idname": "SvNumberNode",
      "height": 100.0,
      "hide": false,
      "label": "SEED",
      "location": [
        -128.67410278320312,
        55.04494857788086
      ],
      "params": {
        "float_": 0.0,
        "int_": 3,
        "selected_mode": "int",
        "show_limits": 0,
        "to3d": 1
      },
      "width": 140.0
    },
    "Frame": {
      "bl_idname": "NodeFrame",
      "color": [
        0.29120713472366333,
        0.060278404504060745,
        0.34509801864624023
      ],
      "height": 772.249267578125,
      "hide": false,
      "label": "Sverchok_viewer",
      "location": [
        -1329.406494140625,
        460.4375305175781
      ],
      "params": {},
      "use_custom_color": true,
      "width": 1785.0301513671875
    },
    "Frame.001": {
      "bl_idname": "NodeFrame",
      "color": [
        0.6080008745193481,
        0.024157192558050156,
        0.03342340886592865
      ],
      "height": 330.1342468261719,
      "hide": false,
      "label": "leaf",
      "location": [
        107.08935546875,
        154.39794921875
      ],
      "params": {},
      "use_custom_color": true,
      "width": 367.027099609375
    },
    "Frame.002": {
      "bl_idname": "NodeFrame",
      "color": [
        0.6080002784729004,
        0.09940759837627411,
        0.051075298339128494
      ],
      "height": 329.6610412597656,
      "hide": false,
      "label": "branch",
      "location": [
        -224.156005859375,
        178.59405517578125
      ],
      "params": {},
      "use_custom_color": true,
      "width": 525.47900390625
    },
    "Frame.003": {
      "bl_idname": "NodeFrame",
      "color": [
        0.8795254230499268,
        1.0,
        0.05101192370057106
      ],
      "height": 400.225830078125,
      "hide": false,
      "label": "tree",
      "location": [
        0.0,
        60.0
      ],
      "params": {},
      "use_custom_color": true,
      "width": 265.2337646484375
    },
    "Frame.004": {
      "bl_idname": "NodeFrame",
      "color": [
        0.054619938135147095,
        0.6080003976821899,
        0.03490321338176727
      ],
      "height": 676.1333618164062,
      "hide": false,
      "label": "points",
      "location": [
        0.0,
        60.0
      ],
      "params": {},
      "use_custom_color": true,
      "width": 752.009521484375
    },
    "Move": {
      "bl_idname": "SvMoveNodeMK2",
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        416.6103515625,
        128.37823486328125
      ],
      "params": {
        "mult_": 1.0,
        "separate": 0
      },
      "width": 140.0
    },
    "Move.001": {
      "bl_idname": "SvMoveNodeMK2",
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        244.1236114501953,
        127.39309692382812
      ],
      "params": {
        "mult_": 0.6000000238418579,
        "separate": 0
      },
      "width": 140.0
    },
    "NGon": {
      "bl_idname": "SvNGonNode",
      "color": [
        0.9200000166893005,
        0.9200000166893005,
        0.9200000166893005
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        1065.7926025390625,
        -1.277557373046875
      ],
      "params": {
        "rad_": 0.10000000149011612,
        "rand_phi_": 1.7400000095367432,
        "rand_r_": 0.12000000476837158,
        "rand_seed_": 0.0,
        "shift_": 0,
        "sides_": 6
      },
      "use_custom_color": true,
      "width": 140.0
    },
    "Note": {
      "bl_idname": "NoteNode",
      "color": [
        1.0,
        0.8993440270423889,
        0.9742509722709656
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        -135.046142578125,
        298.3558654785156
      ],
      "params": {
        "text": "nikitron 2018 - tree Elfnor's scripted node usage example."
      },
      "use_custom_color": true,
      "width": 400.0
    },
    "Pipe": {
      "bl_idname": "SvPipeNode",
      "custom_socket_props": {
        "2": {
          "prop": [
            0.10000000149011612,
            0.10000000149011612,
            1.0
          ],
          "use_prop": true
        }
      },
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        1211.3359375,
        332.540283203125
      ],
      "params": {
        "close": 0,
        "cup_fill": 1,
        "shape": "Round"
      },
      "width": 140.0
    },
    "Random Vector MK2": {
      "bl_idname": "RandomVectorNodeMK2",
      "color": [
        0.0,
        0.5,
        0.5
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        -129.33773803710938,
        183.98480224609375
      ],
      "params": {
        "count_inner": 400,
        "scale": 2.0,
        "seed": 1
      },
      "use_custom_color": true,
      "width": 140.0
    },
    "Scripted Node": {
      "bl_idname": "SvScriptNode",
      "color": [
        0.0,
        0.800000011920929,
        0.949999988079071
      ],
      "height": 100.0,
      "hide": false,
      "label": "tree_generator.py",
      "location": [
        713.6229248046875,
        254.108154296875
      ],
      "params": {
        "button_names": "",
        "float_list": [
          0.0,
          1.0,
          0.15000000596046448,
          0.10000000149011612,
          2.431999921798706,
          0.019999999552965164,
          6.0,
          7.0,
          8.0,
          9.0,
          10.0,
          11.0,
          12.0,
          13.0,
          14.0,
          15.0,
          16.0,
          17.0,
          18.0,
          19.0,
          20.0,
          21.0,
          22.0,
          23.0,
          24.0,
          25.0,
          26.0,
          27.0,
          28.0,
          29.0,
          30.0,
          31.0
        ],
        "has_buttons": 0,
        "int_list": [
          0,
          50,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18,
          19,
          20,
          21,
          22,
          23,
          24,
          25,
          26,
          27,
          28,
          29,
          30,
          31
        ],
        "script_name": "tree_generator.py",
        "script_str": "import numpy as np\nimport time\n\nfrom mathutils import Vector, Matrix    \n\nfrom sverchok.data_structure import Matrix_listing\n\ndef closest_np2(xyz1, xyz2):\n    x2 = np.subtract.outer(xyz2[:,0], xyz1[:,0])\n    y2 = np.subtract.outer(xyz2[:,1], xyz1[:,1])\n    z2 = np.subtract.outer(xyz2[:,2], xyz1[:,2])\n    d2 = np.sum((x2**2, y2**2, z2**2), axis=0)\n    ci = d2.argmin(axis=1)\n    column_i = range(d2.shape[0])\n    dout = np.sqrt(d2[column_i, ci])\n    v = np.vstack((x2[column_i, ci], y2[column_i, ci], z2[column_i, ci]))    \n    return dout, ci, v.T\n\nclass SCA:\n\n    def __init__(self, d=0.3, NBP=2000, KILLDIST=5, INFLUENCE=15, endpoints=[], \n                 TROPISM=0.0, max_time=1.0, startpoints=[]):\n        self.killdistance = KILLDIST\n        self.branchlength = d\n        self.maxiterations = NBP\n        self.tropism = np.array(TROPISM)\n        self.influence = INFLUENCE if INFLUENCE > 0 else 1e16\n        self.max_time = max_time\n        \n        if len(startpoints) > 0:            \n            self.bpalln = np.array(startpoints)\n        else:\n            self.bpalln = np.array([[0, 0, 0]])      \n        \n        self.bpp = [None] * self.bpalln.shape[0]\n        self.bpc = [0] * self.bpalln.shape[0]\n        self.bpg = [0] * self.bpalln.shape[0]\n            \n        self.epn = np.array(endpoints)        \n        d, ci, v = closest_np2(self.bpalln, self.epn)\n        self.epbn = ci\n        self.epdn = d\n        self.epvn = v / self.epdn.reshape((-1, 1))\n        self.epbn[self.epdn >= self.influence] = -2\n        \n        \n    def addBranchPoint(self, bpn, pi, generation):\n        self.bpalln = np.append(self.bpalln, [bpn], axis=0)\n\n        self.bpp.append(pi)\n        self.bpc.append(0)\n        #self.bpg.append(generation + 1)\n        self.bpg = np.append(self.bpg, [generation+1])\n        self.bpc[pi] += 1  \n        bi = self.bpalln.shape[0] - 1\n        v = self.epn - bpn\n        d2 = (v**2).sum(axis=1)\n        index = (self.epbn != -1) & (d2 < self.epdn**2) & (d2 > self.killdistance**2)\n         \n        d  = np.sqrt(d2[index])\n        self.epvn[index] = v[index, :] / d.reshape((-1,1))\n        self.epdn[index] = d\n        \n        index2 = (index & (d2 < self.influence**2))               \n        self.epbn[index2] = bi\n        \n        index3 = (index & (d2 >= self.influence**2))                \n        self.epbn[index3] = -2\n        \n        index4 = (self.epbn != -1) & (d2 < self.epdn**2) & (d2 <= self.killdistance**2)                \n        self.epbn[index4] = -1    \n               \n        if self.bpc[pi] > 1:  # a branch point with two children will not grow any new branches ...\n            index_e = (self.epbn == pi)\n            index_b = (np.array(self.bpc) <= 1)\n            d, c, v = closest_np2(self.bpalln[index_b], self.epn[index_e])\n            # this turns c indixes into self.bpalln[index_b] into u indices into self.bpalln\n            #needs better variable names\n            t = np.arange(self.bpalln.shape[0])[index_b]\n            u = t[c]\n            # set points not within influence distance to -2 so they will be\n            # ignored in growBranches\n            u[d >= self.influence] = -2\n\n            self.epdn[index_e] = d\n            self.epbn[index_e] = u            \n            self.epvn[index_e] = v / d.reshape((-1,1))    \n                         \n    def growBranches(self, generation):\n        index = self.epbn >= 0        \n        epbn = self.epbn[index]\n        bis = np.unique(epbn)\n        \n        v_sums = np.empty((bis.shape[0], 3))\n        for col in range(3):\n            v_sums[:, col] = np.bincount(epbn, weights=self.epvn[index, col])[bis]\n#        d2 = (v_sums**2).sum(axis=1)\n#        d = np.sqrt(d2) /self.branchlength\n#        vd = v_sums / d.reshape((-1, 1))\n\n        n_hat = v_sums/(((v_sums**2).sum(axis=1))**0.5).reshape((-1,1))\n        n_tilde = (n_hat + self.tropism)\n        n_tilde = n_tilde/(((n_tilde**2).sum(axis=1))**0.5).reshape((-1,1))\n       \n        newbps = self.bpalln[bis] + n_tilde * self.branchlength\n        newbpps = bis        \n                \n        for newbp, newbpp in zip(newbps, newbpps):\n            self.addBranchPoint(newbp, newbpp, generation)\n                        \n    def iterate(self):\n        t0 = time.time()\n        for i in range(self.maxiterations):\n            nbp = self.bpalln.shape[0]    \n            self.growBranches(i)\n            if self.bpalln.shape[0] == nbp:\n                return\n            if (time.time() - t0) > self.max_time:\n                print('SCA timed out')\n                return\n        return\n\n    def bp_verts_edges_n(self):\n        \"\"\"\n        returns branchpoints verts as a list of positions\n        and edges as index to connect the branch points\n        and leaves matrices \n        \"\"\"\n        verts = []\n        edges = []\n        ends = []\n        ends_inds = []\n        for i, b in enumerate(self.bpalln):\n            bp_parent = self.bpp[i]\n            verts.append(list(b))\n            if bp_parent != None:\n                edges.append((bp_parent, i))\n            if self.bpc[i] == 0:\n                ends.append(True)\n                ends_inds.append(i)\n            else:\n                ends.append(False)  \n        process = ends_inds\n        # branch radii\n        br = [int(t) for t in ends]\n        finished = []\n        while len(process) > 0:\n            process.sort()\n            i = process.pop()\n            finished.append(i)\n            p = self.bpp[i]\n            if p != None:\n                br[p] = br[p] + br[i]\n                if p not in process:\n                    if p not in finished:\n                        process.insert(0, p)    \n                        \n        mats= []\n        for edge in edges:           \n            if ends[edge[1]]:\n                #calculate leaf directions\n                #end will always be edge[1]\n                v0 = Vector(verts[edge[0]])\n                v1 = Vector(verts[edge[1]])\n                dir1 = (v1 - v0).normalized()\n                dir2 = (dir1.cross(Vector((0.0, 0.0, 1.0)))).normalized()               \n                dir3 = -(dir1.cross(dir2)).normalized() \n                m = Matrix.Identity(4)\n                m[0][0:3] = dir1\n                m[1][0:3] = dir2\n                m[2][0:3] = dir3\n                m[3][0:3] = v1\n                m.transpose()\n                mats.append(m)\n\n        mats_out =  Matrix_listing(mats)\n     \n        return verts, edges, ends, br, mats_out\n        \ndef sv_main(npoints=100 , dist=0.05, min_dist=0.05, max_dist=2.0, tip_radius=0.01, trop=[], verts_in=[], verts_start=[]):\n\n    in_sockets = [\n        ['s', 'maximum branches', npoints],\n        ['s', 'branch length', dist],\n        ['s', 'minimum distance', min_dist],\n        ['s', 'maximum distance', max_dist],\n        ['s', 'tip radius', tip_radius], \n        ['v', 'tropism', trop],\n        ['v', 'End Vertices',  verts_in],\n        ['v', 'Start Vertices', verts_start]\n    ]\n    verts_out = []\n    edges_out = []\n    rad_out = []\n    ends_out = []\n    mats_out = []\n    if not verts_start:\n        verts_start = [[]]\n    if not trop:\n        trop = [0., 0., 0.]    \n        \n    if verts_in :\n        sca = SCA(NBP = npoints,\n                  d=dist,\n                  KILLDIST=min_dist,\n                  INFLUENCE=max_dist, \n                  TROPISM=trop[0],\n                  endpoints=verts_in[0],\n                  startpoints = verts_start[0])\n\n        sca.iterate()\n        verts_out, edges_out, ends_out, br, mats_out = sca.bp_verts_edges_n()\n        rad_out = [tip_radius*b**0.5 for b in br]\n        \n    out_sockets = [\n        ['v', 'Vertices', [verts_out]],\n        ['s', 'Edges', [edges_out]],\n        ['s', 'Branch radii', [rad_out]],\n        ['s', 'Ends mask', [ends_out]],\n        ['m', 'Leaf matrices', mats_out],\n    ]\n\n    return in_sockets, out_sockets"
      },
      "use_custom_color": true,
      "width": 204.8807373046875
    },
    "Vector Noise MK2": {
      "bl_idname": "SvNoiseNodeMK2",
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        62.0498046875,
        120.93081665039062
      ],
      "params": {
        "noise_type": "VORONOI_F3",
        "seed": 3
      },
      "width": 140.0
    },
    "Vector in": {
      "bl_idname": "GenVectorsNode",
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        258.1935729980469,
        -24.5751953125
      ],
      "params": {
        "x_": 0.0,
        "y_": 0.0,
        "z_": 4.0
      },
      "width": 100.0
    },
    "Vector in.001": {
      "bl_idname": "GenVectorsNode",
      "color": [
        0.054160039871931076,
        0.6080000996589661,
        0.053199827671051025
      ],
      "height": 100.0,
      "hide": false,
      "label": "SHAPE",
      "location": [
        429.0069580078125,
        308.7215881347656
      ],
      "params": {
        "x_": 0.0,
        "y_": 0.0,
        "z_": -0.5
      },
      "use_custom_color": true,
      "width": 115.01487731933594
    },
    "Vector in.002": {
      "bl_idname": "GenVectorsNode",
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        1064.152099609375,
        332.540283203125
      ],
      "params": {
        "z_": 1.0
      },
      "width": 100.0
    },
    "Vector in.003": {
      "bl_idname": "GenVectorsNode",
      "color": [
        0.07783515006303787,
        0.6080000996589661,
        0.03712202608585358
      ],
      "height": 100.0,
      "hide": false,
      "label": "START",
      "location": [
        439.8919677734375,
        -55.538787841796875
      ],
      "params": {
        "z_": 0.0
      },
      "use_custom_color": true,
      "width": 100.0
    },
    "Viewer Draw": {
      "bl_idname": "ViewerNode2",
      "color": [
        0.6284880042076111,
        0.931007981300354,
        1.0
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        1232.4669189453125,
        -4.710784912109375
      ],
      "params": {
        "activate": 1,
        "display_edges": 0,
        "display_verts": 0,
        "face_colors": [
          0.03725513443350792,
          0.8990001082420349,
          0.06350543349981308
        ],
        "shading": 1,
        "transparant": 0
      },
      "use_custom_color": true,
      "width": 140.0
    },
    "Viewer Draw.001": {
      "bl_idname": "ViewerNode2",
      "color": [
        0.6284880042076111,
        0.931007981300354,
        1.0
      ],
      "height": 100.0,
      "hide": false,
      "label": "END",
      "location": [
        -125.98733520507812,
        -40.70135498046875
      ],
      "params": {
        "activate": 0,
        "vertex_colors": [
          0.010611055418848991,
          0.0,
          1.0
        ]
      },
      "use_custom_color": true,
      "width": 140.0
    },
    "Viewer Draw.002": {
      "bl_idname": "ViewerNode2",
      "color": [
        1.0,
        0.30000001192092896,
        0.0
      ],
      "height": 100.0,
      "hide": false,
      "label": "",
      "location": [
        1389.2783203125,
        344.48455810546875
      ],
      "params": {
        "activate": 1,
        "display_edges": 0,
        "display_verts": 0,
        "shading": 1
      },
      "use_custom_color": true,
      "width": 140.0
    }
  },
  "update_lists": [
    [
      "Random Vector MK2",
      0,
      "Vector Noise MK2",
      0
    ],
    [
      "A Number",
      0,
      "Vector Noise MK2",
      1
    ],
    [
      "Random Vector MK2",
      0,
      "Move.001",
      0
    ],
    [
      "Vector Noise MK2",
      0,
      "Move.001",
      1
    ],
    [
      "Move.001",
      0,
      "Move",
      0
    ],
    [
      "Vector in",
      0,
      "Move",
      1
    ],
    [
      "Vector in.001",
      0,
      "Scripted Node",
      5
    ],
    [
      "Move",
      0,
      "Scripted Node",
      6
    ],
    [
      "Vector in.003",
      0,
      "Scripted Node",
      7
    ],
    [
      "Scripted Node",
      2,
      "Vector in.002",
      0
    ],
    [
      "Scripted Node",
      2,
      "Vector in.002",
      1
    ],
    [
      "Scripted Node",
      0,
      "Pipe",
      0
    ],
    [
      "Scripted Node",
      1,
      "Pipe",
      1
    ],
    [
      "Vector in.002",
      0,
      "Pipe",
      2
    ],
    [
      "Move",
      0,
      "Viewer Draw.001",
      0
    ],
    [
      "Pipe",
      0,
      "Viewer Draw.002",
      0
    ],
    [
      "Pipe",
      1,
      "Viewer Draw.002",
      1
    ],
    [
      "NGon",
      0,
      "Viewer Draw",
      0
    ],
    [
      "NGon",
      2,
      "Viewer Draw",
      1
    ],
    [
      "Scripted Node",
      4,
      "Viewer Draw",
      2
    ]
  ]
}