{"action":"created","issue":{"url":"https://api.github.com/repos/zeffii/BlenderLSystem3D/issues/2","repository_url":"https://api.github.com/repos/zeffii/BlenderLSystem3D","labels_url":"https://api.github.com/repos/zeffii/BlenderLSystem3D/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/zeffii/BlenderLSystem3D/issues/2/comments","events_url":"https://api.github.com/repos/zeffii/BlenderLSystem3D/issues/2/events","html_url":"https://github.com/zeffii/BlenderLSystem3D/issues/2","id":151643026,"number":2,"title":"plant 2 - using skin modifier ( System + Rules)","user":{"login":"zeffii","id":619340,"avatar_url":"https://avatars.githubusercontent.com/u/619340?v=3","gravatar_id":"","url":"https://api.github.com/users/zeffii","html_url":"https://github.com/zeffii","followers_url":"https://api.github.com/users/zeffii/followers","following_url":"https://api.github.com/users/zeffii/following{/other_user}","gists_url":"https://api.github.com/users/zeffii/gists{/gist_id}","starred_url":"https://api.github.com/users/zeffii/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zeffii/subscriptions","organizations_url":"https://api.github.com/users/zeffii/orgs","repos_url":"https://api.github.com/users/zeffii/repos","events_url":"https://api.github.com/users/zeffii/events{/privacy}","received_events_url":"https://api.github.com/users/zeffii/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-04-28T13:37:00Z","updated_at":"2016-04-29T12:34:09Z","closed_at":null,"body":"```python\r\nimport math\r\nfrom math import radians\r\nimport random\r\nfrom random import randint\r\nimport ast\r\n\r\nimport bmesh\r\nimport mathutils\r\nfrom mathutils import Vector, Euler\r\n\r\n\"\"\"\r\nlifted from: http://www.4dsolutions.net/ocn/lsystems.html\r\n\"\"\"\r\n\r\n\r\n\r\nclass Lturtle:\r\n\r\n    import mathutils\r\n    from mathutils import Vector, Euler\r\n    Xvec = Vector((1, 0, 0))\r\n    Yvec = Vector((0, 1, 0))\r\n    Zvec = Vector((0, 0, 1))\r\n\r\n    # looking down on YX axis. Z is vertical.\r\n\r\n    stackstate = []    # remembers saved state\r\n    delta = 0.2     # angle of rotation\r\n    length = 0.5   # full length of turtle move\r\n    thickness = 0.02  # default thickness of cylinder\r\n    instrudict = {\r\n        '+': 'turnleft',\r\n        '-': 'turnright',\r\n        '&': 'pitchdown',\r\n        '^': 'pitchup',\r\n        '<': 'leftroll',\r\n        '>': 'rightroll',\r\n        '[': 'storeloc_rot',\r\n        ']': 'restoreloc_rot',\r\n        '%': 'roll180',\r\n        '$': 'rollhoriz',\r\n        'x': 'randturn',\r\n        't': 'gravity',\r\n        'F': 'fdraw',\r\n        'f': 'fnodraw',\r\n        'Z': 'halfdraw',\r\n        'z': 'halfnodraw',\r\n        'g': 'Fnorecord',\r\n        '.': 'Nomove',\r\n        's': 'set_scale',\r\n        '{': 'store_scale',\r\n        '}': 'restore_scale'\r\n    }\r\n\r\n    stored_states = []\r\n    stored_radius = []\r\n    radii = []\r\n    verts = []\r\n    edges = []\r\n    start_scale = 1.0\r\n\r\n    def __init__(self, vPos=Vector((0, 0, 0))):\r\n        self.vHeading = Vector((0, 0, 1))\r\n        self.vPos = vPos\r\n        self.delta = 0.2\r\n        self.amp = 1.0\r\n        self.scale = 1.0\r\n\r\n    def chomp(self, instructions):\r\n\r\n        self.scale *= self.start_scale\r\n\r\n        getparam = 0\r\n        checkparam = 0\r\n        param = \"\"\r\n\r\n        for item in instructions:\r\n\r\n            if getparam:\r\n                if item == \")\":\r\n                    getparam = 0  # done getting\r\n                    command = command + \"(\" + param + \")\"\r\n                    eval(command)\r\n                    continue\r\n                else:\r\n                    param = param + item  # building parameter\r\n                    continue\r\n\r\n            if checkparam:        # checking for parameter?\r\n                checkparam = 0\r\n                if item == \"(\":\r\n                    param = \"\"\r\n                    getparam = 1  # parameter exists\r\n                    continue\r\n                else:\r\n                    command = command + \"()\"  # no parameter\r\n                    eval(command)\r\n\r\n            # initializing command string\r\n            command = \"self.\" + self.instrudict.get(item, 'notHandled')\r\n            checkparam = 1    # set flag\r\n\r\n        else:  # dealing with last item\r\n            if checkparam:\r\n                command = command + \"()\"  # no parameter\r\n                eval(command)\r\n\r\n    def add_edge(self):\r\n        i = len(self.verts)\r\n        self.edges.append([i - 2, i - 1])\r\n\r\n    def add_verts(self, amp=1):\r\n        self.verts.append(self.vPos[:])\r\n        self.vPos = self.vPos + (self.vHeading * self.length * amp)\r\n        self.verts.append(self.vPos[:])\r\n        self.radii.extend([self.thickness, self.thickness])\r\n\r\n    def fnodraw(self, n=\"\"):\r\n        self.vPos = self.vPos + self.vHeading * self.length\r\n        print(\"Forward %s (no draw)\" % n)\r\n\r\n    def halfnodraw(self, n=\"\"):\r\n        self.vPos = self.vPos + (self.vHeading * self.length * 0.5)\r\n        print(\"half no draw %s\" % n)\r\n\r\n    def fdraw(self, n=\"\"):\r\n        self.add_verts()\r\n        self.add_edge()\r\n        print(\"fdraw %s\" % n)\r\n\r\n    def halfdraw(self, n=\"\"):\r\n        self.add_verts(amp=0.5)\r\n        self.add_edge()\r\n        print(\"half draw %s\" % n)\r\n\r\n    # Turning, Pitch, Roll\r\n    def storeloc_rot(self, n=\"\"):\r\n        self.stored_states.append([self.vPos, self.vHeading])\r\n        print(\"Store rotation and location %s\" % n)\r\n\r\n    def restoreloc_rot(self, n=\"\"):\r\n        if len(self.stored_states) > 0:\r\n            self.vPos, self.vHeading = self.stored_states.pop()\r\n            print(\"Restore rotation and location %s\" % n)\r\n        else:\r\n            print('tried restore loc/rot but stored states was empty. you suck :)')\r\n\r\n    def do_rotation(self, axis, sign, n=\"\"):\r\n        \"\"\" axis 0=x, 1=y, z=2 \"\"\"\r\n        if n:\r\n            self.delta = float(n)\r\n        components = [0, 0, 0]\r\n        components[axis] = sign * radians(self.delta) * self.amp\r\n        myEul = Euler(components, 'XYZ')\r\n        self.vHeading.rotate(myEul)\r\n\r\n    def turnleft(self, n=\"\"):\r\n        self.do_rotation(1, 2, n)\r\n        print(\"Turn Left around Z axis %s\" % n)\r\n\r\n    def turnright(self, n=\"\"):\r\n        self.do_rotation(-1, 2, n)\r\n        print(\"Turn Right around Z axis %s\" % n)\r\n\r\n    def pitchdown(self, n=\"\"):\r\n        self.do_rotation(1, 1, n)\r\n        print(\"Pitch down %s\" % n)\r\n\r\n    def pitchup(self, n=\"\"):\r\n        self.do_rotation(-1, 1, n)\r\n        print(\"Pitch up %s\" % n)\r\n\r\n    def leftroll(self, n=\"\"):\r\n        self.do_rotation(1, 0, n)\r\n        print(\"left roll %s\" % n)\r\n\r\n    def rightroll(self, n=\"\"):\r\n        self.do_rotation(-1, 0, n)\r\n        print(\"right roll %s\" % n)\r\n\r\n    def turn180(self, n=\"\"):\r\n        self.do_rotation(-1, 2, 180)\r\n        print(\"turn180 %s\" % n)\r\n\r\n    def roll180(self, n=\"\"):\r\n        self.do_rotation(1, 0, 180)\r\n        print(\"roll180 %s\" % n)\r\n\r\n    def rollhoriz(self, n=\"\"):\r\n        # not exactly sure what this command was intended to do but how\r\n        # about resetting to vertical.\r\n        self.vHeading = Vector((0, 0, 1))\r\n        print(\"roll horiz %s\" % n)\r\n\r\n    def randturn(self, n=\"\"):\r\n        ax_x = radians(randint(0, 360))\r\n        ax_y = radians(randint(0, 360))\r\n        ax_z = radians(randint(0, 360))\r\n        myEul = Euler((ax_x, ax_y, ax_z), 'XYZ')\r\n        self.vHeading.rotate(myEul)\r\n        print(\"randturn %s\" % n)\r\n\r\n    def gravity(self, n=\"\"):\r\n        print(\"not handled yet\")\r\n        print(\"gravity %s\" % n)\r\n\r\n    def Fnorecord(self, n=\"\"):\r\n        print(\"Fnorecord %s\" % n)\r\n\r\n    def Nomove(self, n=\"\"):\r\n        print(\"No move %s\" % n)\r\n\r\n    def notHandled(self, n=\"\"):\r\n        print(\"Not handled %s\" % n)\r\n    \r\n    def set_scale(self, n=\"\"):\r\n        if n:\r\n            self.thickness *= float(n)\r\n\r\n    def store_scale(self, n=\"\"):\r\n        self.stored_radius.append(self.thickness)\r\n\r\n    def restore_scale(self, n=\"\"):\r\n        self.thickness = self.stored_radius.pop()\r\n\r\n\r\ndef sv_main(t_angle=0.2, t_scale=0.4):\r\n    verts_out = []\r\n    edges_out = []\r\n    radii_out = []\r\n\r\n    in_sockets = [\r\n        ['s', 't_angle', t_angle],\r\n        ['s', 't_scale', t_scale]\r\n    ]\r\n\r\n    def produce(axiom, rules):\r\n        output = \"\"\r\n        for i in axiom:\r\n            output = output + rules.get(i, i)\r\n        return output\r\n\r\n\r\n    def iterate(n, axiom, rules):\r\n        if n > 0:\r\n            axiom = produce(axiom, rules)\r\n            return iterate(n - 1, axiom, rules)\r\n        return axiom\r\n\r\n    texts = bpy.data.texts\r\n    f = texts['RULES'].as_string()\r\n    rules = {}\r\n    rules = ast.literal_eval(f)\r\n    axiom = 'I'\r\n\r\n    m = iterate(5, axiom, rules)\r\n    \r\n    # ffff = 'poonjab' in globals()\r\n    \r\n    poonjab = Lturtle()\r\n    poonjab.verts = []\r\n    poonjab.edges = []\r\n    poonjab.radii = []\r\n    poonjab.amp = t_angle\r\n    poonjab.start_scale = t_scale\r\n    poonjab.chomp(m)\r\n    \r\n    verts_out.extend(poonjab.verts)\r\n    edges_out.extend(poonjab.edges)\r\n    radii_out.extend(poonjab.radii)\r\n\r\n    out_sockets = [\r\n        ['v', 'verts', [verts_out]],\r\n        ['s', 'edges', [edges_out]],\r\n        ['s', 'radii', [radii_out]]\r\n    ]\r\n\r\n    return in_sockets, out_sockets\r\n```\r\nrules\r\n```python\r\n{\r\n  'I': 'FFFs(0.9)FHKH[HKHHHeG]HF[KHHHHHFeFF]eH',\r\n  'H': '-(31)es(0.9)',\r\n  'K': '+(31)Gs(0.9)',  \r\n  'G': 'd+(30)s(0.9)[d]',\r\n  'e': '+(20)F',\r\n  'd': '[F+(-10)>(58)Z-(315)FF-(151)Ff][F(38)+(15)F+(151)F]'\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/zeffii/BlenderLSystem3D/issues/comments/215699258","html_url":"https://github.com/zeffii/BlenderLSystem3D/issues/2#issuecomment-215699258","issue_url":"https://api.github.com/repos/zeffii/BlenderLSystem3D/issues/2","id":215699258,"user":{"login":"zeffii","id":619340,"avatar_url":"https://avatars.githubusercontent.com/u/619340?v=3","gravatar_id":"","url":"https://api.github.com/users/zeffii","html_url":"https://github.com/zeffii","followers_url":"https://api.github.com/users/zeffii/followers","following_url":"https://api.github.com/users/zeffii/following{/other_user}","gists_url":"https://api.github.com/users/zeffii/gists{/gist_id}","starred_url":"https://api.github.com/users/zeffii/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zeffii/subscriptions","organizations_url":"https://api.github.com/users/zeffii/orgs","repos_url":"https://api.github.com/users/zeffii/repos","events_url":"https://api.github.com/users/zeffii/events{/privacy}","received_events_url":"https://api.github.com/users/zeffii/received_events","type":"User","site_admin":false},"created_at":"2016-04-29T12:34:09Z","updated_at":"2016-04-29T12:34:09Z","body":"some keyframing:\r\n![foooozle](https://cloud.githubusercontent.com/assets/619340/14916034/6ad0a2e2-0e17-11e6-9a12-605dda92f077.gif)\r\n"}}