{
  "Name": "Cylinder",
  "_id": "dcc5ec2f-ed1c-4b2a-b227-d13d57a5e37a",
  "Namespace": "lib.3d.generate",
  "Description": "Renders a cylinder.",
  "Inputs": [
    {
      "Name": "Radius.Top",
      "MetaInstanceID": "0767518b-1c4b-4684-9288-f1bb64b8ed55",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0.5"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Radius.Bottom",
      "MetaInstanceID": "95b7d6f4-9d26-4e73-bf91-5ecafe730fba",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0.5"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Tessellate.Caps",
      "MetaInstanceID": "51a82624-780e-493a-bee0-212892fa4c82",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "1",
      "Max": "250",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Tessellate.Radius",
      "MetaInstanceID": "bc25d8cd-4410-4c4a-b8f4-c57da2cd5a39",
      "DefaultValue": {
        "Type": "Float",
        "Value": "12"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "3",
      "Max": "200",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Spin.Hull",
      "MetaInstanceID": "74c03208-797f-4636-916e-e8be76e956a9",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Portion.Hull",
      "MetaInstanceID": "f057490a-68a1-4e23-8b1a-ef406963e66d",
      "DefaultValue": {
        "Type": "Float",
        "Value": "360"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "360",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Color.R",
      "MetaInstanceID": "cd61fd1c-c17d-4fc5-9625-cc343cd4cd34",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "1",
      "Scale": "0.01",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Color.G",
      "MetaInstanceID": "0f95b38c-bcab-42d4-8d5f-02a99d0e7c53",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "1",
      "Scale": "0.01",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Color.B",
      "MetaInstanceID": "cf80c430-56d2-4b25-8f73-c2bce739c08a",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "1",
      "Scale": "0.01",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Color.A",
      "MetaInstanceID": "9c5797a9-1c56-444e-a97d-2f45f5d81977",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "1",
      "Scale": "0.01",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "SmoothAngle",
      "MetaInstanceID": "f93bb148-399b-4740-afb3-4d09aa46d999",
      "DefaultValue": {
        "Type": "Float",
        "Value": "30"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Height",
      "MetaInstanceID": "a0790c03-c685-4f6e-a9f7-bf0b6260f830",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Draw Caps",
      "MetaInstanceID": "cb909431-6d33-4afb-960f-5d131ac61366",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": [
        {
          "Name": "Both",
          "Value": "0"
        },
        {
          "Name": "Top only",
          "Value": "1"
        },
        {
          "Name": "Bottom only",
          "Value": "2"
        },
        {
          "Name": "None",
          "Value": "4"
        }
      ]
    },
    {
      "Name": "Tessellate.Height",
      "MetaInstanceID": "41506ab4-0fa9-4724-86ef-82e5e6aa78e4",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "1",
      "Max": "100000",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    }
  ],
  "Outputs": [
    {
      "Name": "Out",
      "MetaInstanceID": "dfb24194-2146-4b22-bbd3-b478a11689e5",
      "MetaID": "79122951-7bc4-4c68-b085-866eab828248"
    }
  ],
  "OperatorParts": [
    {
      "MetaInstanceID": "b147e0f3-3c06-4953-8a67-fe2251a4024f",
      "MetaID": "272b2877-fc59-495a-8a04-20e42e0b7629",
      "Name": "CylinderFunc",
      "Version": "6aea68a2-7242-480a-8621-0c140430dc3b",
      "Type": "Scene",
      "IsMultiInput": "True",
      "Script": [
        "using System;",
        "using System.Collections.Generic;",
        "using SharpDX;",
        "using SharpDX.Direct3D11;",
        "using Framefield.Core.OperatorPartTraits;",
        "using Framefield.Core.Rendering;",
        "using Buffer = SharpDX.Direct3D11.Buffer;",
        "",
        "namespace Framefield.Core.ID272b2877_fc59_495a_8a04_20e42e0b7629",
        "{",
        "    public class Class_Cylinder : OperatorPart.Function,",
        "                               IMeshSupplier",
        "    {",
        "        //>>> _inputids",
        "        private enum InputId",
        "        {",
        "            RadiusTop = 0,",
        "            RadiusBottom = 1,",
        "            TessellateCaps = 2,",
        "            TessellateRadius = 3,",
        "            SpinHull = 4,",
        "            PortionHull = 5,",
        "            ColorR = 6,",
        "            ColorG = 7,",
        "            ColorB = 8,",
        "            ColorA = 9,",
        "            SmoothAngle = 10,",
        "            Height = 11,",
        "            DrawCaps = 12,",
        "            TessellateHeight = 13",
        "        }",
        "        //<<< _inputids",
        "",
        "",
        "        // IMeshSupplier",
        "        public void AddMeshesTo(ICollection<Mesh> meshes)",
        "        {",
        "            UpdateMesh(new OperatorPartContext(), OperatorPart.Connections);",
        "            meshes.Add(_torus);",
        "        }",
        "",
        "        public override void Dispose()",
        "        {",
        "            _torus.Dispose();",
        "        }",
        "",
        "        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)",
        "        {",
        "            try",
        "            {",
        "                UpdateMesh(context, inputs);",
        "",
        "                context.Renderer.SetupEffect(context);",
        "                context.Renderer.Render(_torus, context);",
        "            }",
        "            catch (Exception ex)",
        "            {",
        "                Logger.Error(this, \"error {0}\", ex);",
        "            }",
        "",
        "            return context;",
        "        }",
        "",
        "        private void UpdateMesh(OperatorPartContext context, IList<OperatorPart> inputs)",
        "        {",
        "            if (_torus != null && !Changed)",
        "                return;",
        "",
        "            var RadiusTop = inputs[(int)InputId.RadiusTop].Eval(context).Value;",
        "            var RadiusBottom = inputs[(int)InputId.RadiusBottom].Eval(context).Value;",
        "",
        "            var tessCaps = Math.Max(1, (int)inputs[(int)InputId.TessellateCaps].Eval(context).Value);",
        "            var tessRadius = Math.Max(3, (int)inputs[(int)InputId.TessellateRadius].Eval(context).Value);",
        "            var tessHeight = Math.Max(1, (int)inputs[(int)InputId.TessellateHeight].Eval(context).Value);",
        "",
        "            var spinHullInRad = Utilities.DegreeToRad(inputs[(int)InputId.SpinHull].Eval(context).Value);",
        "",
        "            var portionHull = inputs[(int)InputId.PortionHull].Eval(context).Value / 360.0;",
        "",
        "            var colorR = inputs[(int)InputId.ColorR].Eval(context).Value;",
        "            var colorG = inputs[(int)InputId.ColorG].Eval(context).Value;",
        "            var colorB = inputs[(int)InputId.ColorB].Eval(context).Value;",
        "            var colorA = inputs[(int)InputId.ColorA].Eval(context).Value;",
        "            var smoothAngle = inputs[(int)InputId.SmoothAngle].Eval(context).Value;",
        "",
        "            var height = (float)inputs[(int)InputId.Height].Eval(context).Value;",
        "",
        "            var drawCaps = inputs[(int)InputId.DrawCaps].Eval(context).Value;",
        "            var drawTop = (drawCaps == 0) || (drawCaps == 1);",
        "            var drawBottom = (drawCaps == 0) || (drawCaps == 2);",
        "",
        "            var uvCenterTopCap = new Vector2(0.225f, 0.25f);",
        "",
        "            var uvCenterBottomCap = new Vector2(0.775f, 0.25f);",
        "",
        "            Dispose();",
        "            var color = new Vector4(colorR, colorG, colorB, colorA);",
        "            var tangent = new Vector3(0.0f, 0.0f, 1.0f);",
        "            var binormal = new Vector3(1.0f, 0.0f, 0.0f);",
        "",
        "            var inputElements = new[]",
        "                                    {",
        "                                        new InputElement(\"POSITION\", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 0, 0),",
        "                                        new InputElement(\"NORMAL\", 0, SharpDX.DXGI.Format.R32G32B32_Float, 16, 0),",
        "                                        new InputElement(\"COLOR\", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 28, 0),",
        "                                        new InputElement(\"TEXCOORD\", 0, SharpDX.DXGI.Format.R32G32_Float, 44, 0),",
        "                                        new InputElement(\"TANGENT\", 0, SharpDX.DXGI.Format.R32G32B32_Float, 52, 0),",
        "                                        new InputElement(\"BINORMAL\", 0, SharpDX.DXGI.Format.R32G32B32_Float, 64, 0)",
        "                                    };",
        "            ",
        "            int numQuadsForHull = tessRadius * tessHeight ;",
        "            int numQuadsCaps = tessCaps * tessRadius;",
        "            int numQuads = numQuadsForHull ",
        "                           + (drawTop    ? numQuadsCaps :0)  ",
        "                           + (drawBottom ? numQuadsCaps :0);",
        "                                    ",
        "            bool smoothHull = portionHull / (int)tessRadius > smoothAngle / 360;",
        "            const int attributesSize = 76;",
        "            int numTriangles = numQuads * 2;",
        "            ",
        "            int streamSize =  numTriangles * 3 * attributesSize;",
        "            using (var vertexStream = new DataStream(streamSize, true, true))",
        "            {",
        "                double hullAngleFraction = portionHull / tessRadius * 2.0 * Math.PI;",
        "",
        "                for (int z = 0; z < tessRadius; ++z)",
        "                {",
        "                    double tubeAngle = z * hullAngleFraction + spinHullInRad;",
        "                    float tubePosition1Ytop = (float)Math.Cos(tubeAngle) * RadiusTop;",
        "                    float tubePosition1Xtop = (float)Math.Sin(tubeAngle) * RadiusTop;",
        "                    float tubePosition2Ytop = (float)Math.Cos(tubeAngle + hullAngleFraction) * RadiusTop;",
        "                    float tubePosition2Xtop = (float)Math.Sin(tubeAngle + hullAngleFraction) * RadiusTop;",
        "                    float tubePositionZtop = (float)0.5f * height;",
        "",
        "                    float Pos1YFraction = (float)Math.Cos(tubeAngle) * (RadiusTop - RadiusBottom) / tessHeight;",
        "                    float Pos1XFraction = (float)Math.Sin(tubeAngle) * (RadiusTop - RadiusBottom) / tessHeight;",
        "                    float Pos2YFraction = (float)Math.Cos(tubeAngle + hullAngleFraction) * (RadiusTop - RadiusBottom) / tessHeight;",
        "                    float Pos2XFraction = (float)Math.Sin(tubeAngle + hullAngleFraction) * (RadiusTop - RadiusBottom) / tessHeight;",
        "                    float PosZFraction = (float)height / tessHeight;",
        "",
        "                    float u0 = (float)((z) / (tessRadius * 1.0f));",
        "                    float u1 = (float)((z + 1) / (tessRadius * 1.0f));",
        "",
        "                    float v0 = 0;",
        "                    float v1 = 0;",
        "",
        "                    var uv0 = new Vector2(u1, v0);",
        "                    var uv1 = new Vector2(u1, v1);",
        "                    var uv2 = new Vector2(u0, v0);",
        "                    var uv3 = new Vector2(u0, v1);",
        "",
        "                    // calc the 4 vertices of quad",
        "                    var p1 = new Vector3((tubePosition2Ytop),",
        "                                         tubePositionZtop, tubePosition2Xtop);",
        "                    var p0 = p1;",
        "                    var p3 = new Vector3((tubePosition1Ytop),",
        "                                         tubePositionZtop, tubePosition1Xtop);",
        "                    var p2 = p3;",
        "",
        "",
        "",
        "                    var tubeCenter1 = new Vector3((float)0, 0.0f, 0.0f);",
        "                    var tubeCenter2 = new Vector3(0.0f, -0.5f * height, 0.0f);",
        "                    //var normal0 = Vector3.Normalize(p0 - tubeCenter2);",
        "                    //var normal1 = Vector3.Normalize(p1 - tubeCenter1);",
        "                    //var normal2 = Vector3.Normalize(p2 - tubeCenter1);",
        "                    //var normal3 = Vector3.Normalize(p3 - tubeCenter2);",
        "                    Vector3 normal0;",
        "                    Vector3 normal1;",
        "                    Vector3 normal2;",
        "                    Vector3 normal3;",
        "",
        "                    Vector3 tangent0, binormal0;",
        "",
        "                    Vector3 tangent1, binormal1;",
        "",
        "                    Vector3 tangent2, binormal2;",
        "",
        "                    Vector3 tangent3, binormal3;",
        "",
        "                    for (int y = 0; y < tessHeight; y++)",
        "                    {",
        "",
        "                        p0.X -= Pos2YFraction; p0.Y -= PosZFraction; p0.Z -= Pos2XFraction;",
        "                        p2.X -= Pos1YFraction; p2.Y -= PosZFraction; p2.Z -= Pos1XFraction;",
        "",
        "                        v0 = 0.5f + (y + 1) / (tessHeight * 2.0f);",
        "                        v1 = 0.5f + (y) / (tessHeight * 2.0f);",
        "",
        "                        uv0.Y = v0;",
        "                        uv1.Y = v1;",
        "                        uv2.Y = v0;",
        "                        uv3.Y = v1;",
        "",
        "",
        "                        var heightCenterTop = new Vector3(0.0f, tubePositionZtop - y * PosZFraction, 0.0f);",
        "                        var heightCenterBot = new Vector3(0.0f, tubePositionZtop - (y + 1) * PosZFraction, 0.0f);",
        "                        //var normal0 = Vector3.Normalize(p0 - tubeCenter2);",
        "                        //var normal1 = Vector3.Normalize(p1 - tubeCenter1);",
        "                        //var normal2 = Vector3.Normalize(p2 - tubeCenter1);",
        "                        //var normal3 = Vector3.Normalize(p3 - tubeCenter2);",
        "                        normal0 = Vector3.Normalize(smoothHull ? Vector3.Cross(p0 - p3, p0 - p1) : p0 - heightCenterBot);",
        "                        normal1 = Vector3.Normalize(smoothHull ? Vector3.Cross(p1 - p0, p1 - p3) : p1 - heightCenterTop);",
        "                        normal2 = Vector3.Normalize(smoothHull ? Vector3.Cross(p2 - p3, p2 - p0) : p2 - heightCenterBot);",
        "                        normal3 = Vector3.Normalize(smoothHull ? Vector3.Cross(p3 - p0, p3 - p2) : p3 - heightCenterTop);",
        "",
        "                        MeshUtilities.CalcTBNSpace(p0, uv0, p3, uv3, p1, uv1, normal0, out tangent0, out binormal0);",
        "",
        "                        MeshUtilities.CalcTBNSpace(p1, uv1, p0, uv0, p3, uv3, normal1, out tangent1, out binormal1);",
        "",
        "                        MeshUtilities.CalcTBNSpace(p2, uv2, p3, uv3, p0, uv0, normal2, out tangent2, out binormal2);",
        "",
        "                        MeshUtilities.CalcTBNSpace(p3, uv3, p0, uv0, p2, uv2, normal3, out tangent3, out binormal3);",
        "",
        "                        // tri 1 vert 1",
        "                        vertexStream.Write(new Vector4(p3, 1));",
        "                        vertexStream.Write(normal3);",
        "                        vertexStream.Write(color);",
        "                        vertexStream.Write(uv3);",
        "                        vertexStream.Write(tangent3);",
        "                        vertexStream.Write(binormal3);",
        "",
        "                        // tri 1 vert 2",
        "                        vertexStream.Write(new Vector4(p1, 1));",
        "                        vertexStream.Write(normal1);",
        "                        vertexStream.Write(color);",
        "                        vertexStream.Write(uv1);",
        "                        vertexStream.Write(tangent1);",
        "                        vertexStream.Write(binormal1);",
        "",
        "",
        "                        // tri 1 vert 3",
        "                        vertexStream.Write(new Vector4(p0, 1));",
        "                        vertexStream.Write(normal0);",
        "                        vertexStream.Write(color);",
        "                        vertexStream.Write(uv0);",
        "                        vertexStream.Write(tangent0);",
        "                        vertexStream.Write(binormal0);",
        "",
        "                        // tri 2 vert 1",
        "                        vertexStream.Write(new Vector4(p0, 1));",
        "                        vertexStream.Write(normal0);",
        "                        vertexStream.Write(color);",
        "                        vertexStream.Write(uv0);",
        "                        vertexStream.Write(tangent0);",
        "                        vertexStream.Write(binormal0);",
        "",
        "                        // tri 2 vert 2",
        "                        vertexStream.Write(new Vector4(p2, 1));",
        "                        vertexStream.Write(normal2);",
        "                        vertexStream.Write(color);",
        "                        vertexStream.Write(uv2);",
        "                        vertexStream.Write(tangent2);",
        "                        vertexStream.Write(binormal2);",
        "",
        "",
        "                        // tri 2 vert 3",
        "                        vertexStream.Write(new Vector4(p3, 1));",
        "                        vertexStream.Write(normal3);",
        "                        vertexStream.Write(color);",
        "                        vertexStream.Write(uv3);",
        "                        vertexStream.Write(tangent3);",
        "                        vertexStream.Write(binormal3);",
        "",
        "                        // update vertices",
        "                        p1 = p0;",
        "                        p3 = p2;",
        "",
        "                    }",
        "",
        "                    p1 = new Vector3((tubePosition2Ytop),",
        "                                         tubePositionZtop, tubePosition2Xtop);",
        "                    p3 = new Vector3((tubePosition1Ytop),",
        "                                         tubePositionZtop, tubePosition1Xtop);",
        "",
        "                    // now the caps",
        "                    var tubeCenter3 = new Vector3(0.0f, 0.5f * height, 0.0f);",
        "",
        "                    // top cap",
        "                    Vector3 tangent4, binormal4;",
        "                    var normal4 = Vector3.Normalize(tubeCenter3);",
        "                    MeshUtilities.CalcTBNSpace(tubeCenter3, uv0, p3, uv1, p1, uv2, normal4, out tangent4, out binormal4);",
        "",
        "                    // bottom cap",
        "                    Vector3 tangent5, binormal5;",
        "                    var normal5 = Vector3.Normalize(tubeCenter2);",
        "                    MeshUtilities.CalcTBNSpace(tubeCenter2, uv0, p2, uv1, p0, uv2, normal5, out tangent5, out binormal5);",
        "",
        "                    if (drawTop || drawBottom)",
        "                    {",
        "                        var uvAngle1 = 2 * Math.PI * (z - 0.5f) / tessRadius;",
        "                        var uvAngle0 = 2 * Math.PI * (z + 0.5f) / tessRadius;",
        "",
        "",
        "                        for (int x = 0; x < tessCaps; ++x)",
        "                        {",
        "                            var decreaseScale = (float)(tessCaps - x - 1) / (tessCaps - x);",
        "                            var p5 = new Vector3(p1.X * decreaseScale, p1.Y, p1.Z * decreaseScale);",
        "                            var p6 = new Vector3(p3.X * decreaseScale, p3.Y, p3.Z * decreaseScale);",
        "                            var p7 = new Vector3(p0.X * decreaseScale, p0.Y, p0.Z * decreaseScale);",
        "                            var p8 = new Vector3(p2.X * decreaseScale, p2.Y, p2.Z * decreaseScale);",
        "",
        "",
        "                            if (drawTop)",
        "                            {",
        "",
        "                                uv0 = uv2 = new Vector2((float)Math.Cos(uvAngle0), -(float)Math.Sin(uvAngle0));",
        "                                uv1 = uv3 = new Vector2((float)Math.Cos(uvAngle1), -(float)Math.Sin(uvAngle1));",
        "",
        "                                uv0 *= 0.2f * (tessCaps - x) / tessCaps;",
        "                                uv1 *= 0.2f * (tessCaps - x) / tessCaps;",
        "                                uv2 *= 0.2f * (tessCaps - x - 1) / tessCaps;",
        "                                uv3 *= 0.2f * (tessCaps - x - 1) / tessCaps;",
        "",
        "                                uv0 += uvCenterTopCap;",
        "                                uv1 += uvCenterTopCap;",
        "                                uv2 += uvCenterTopCap;",
        "                                uv3 += uvCenterTopCap;",
        "",
        "                                // outter tri vert 1",
        "                                vertexStream.Write(new Vector4(p1, 1));",
        "                                vertexStream.Write(normal4);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv0);",
        "                                vertexStream.Write(tangent4);",
        "                                vertexStream.Write(binormal4);",
        "",
        "                                // outter tri vert 2",
        "                                vertexStream.Write(new Vector4(p3, 1));",
        "                                vertexStream.Write(normal4);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv1);",
        "                                vertexStream.Write(tangent4);",
        "                                vertexStream.Write(binormal4);",
        "",
        "                                // outter tri vert 3",
        "                                vertexStream.Write(new Vector4(p5, 1));",
        "                                vertexStream.Write(normal4);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv2);",
        "                                vertexStream.Write(tangent4);",
        "                                vertexStream.Write(binormal4);",
        "",
        "                                // inner tri vert 1",
        "                                vertexStream.Write(new Vector4(p5, 1));",
        "                                vertexStream.Write(normal4);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv2);",
        "                                vertexStream.Write(tangent4);",
        "                                vertexStream.Write(binormal4);",
        "",
        "                                // inner tri vert 2",
        "                                vertexStream.Write(new Vector4(p3, 1));",
        "                                vertexStream.Write(normal4);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv1);",
        "                                vertexStream.Write(tangent4);",
        "                                vertexStream.Write(binormal4);",
        "",
        "                                // inner tri vert 3",
        "                                vertexStream.Write(new Vector4(p6, 1));",
        "                                vertexStream.Write(normal4);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv3);",
        "                                vertexStream.Write(tangent4);",
        "                                vertexStream.Write(binormal4);",
        "",
        "                                p1 = p5;",
        "                                p3 = p6;",
        "                            }",
        "",
        "                            if (drawBottom)",
        "                            {",
        "",
        "                                uv0 = uv2 = new Vector2((float)Math.Cos(uvAngle1), (float)Math.Sin(uvAngle1));",
        "                                uv1 = uv3 = new Vector2((float)Math.Cos(uvAngle0), (float)Math.Sin(uvAngle0));",
        "",
        "                                uv0 *= 0.2f * (tessCaps - x) / tessCaps;",
        "                                uv1 *= 0.2f * (tessCaps - x) / tessCaps;",
        "                                uv2 *= 0.2f * (tessCaps - x - 1) / tessCaps;",
        "                                uv3 *= 0.2f * (tessCaps - x - 1) / tessCaps;",
        "",
        "                                uv0 += uvCenterBottomCap;",
        "                                uv1 += uvCenterBottomCap;",
        "                                uv2 += uvCenterBottomCap;",
        "                                uv3 += uvCenterBottomCap;",
        "                                // outter tri vert 1",
        "                                vertexStream.Write(new Vector4(p7, 1));",
        "                                vertexStream.Write(normal5);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv3);",
        "                                vertexStream.Write(tangent5);",
        "                                vertexStream.Write(binormal5);",
        "",
        "                                // outter tri vert 2",
        "                                vertexStream.Write(new Vector4(p2, 1));",
        "                                vertexStream.Write(normal5);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv0);",
        "                                vertexStream.Write(tangent5);",
        "                                vertexStream.Write(binormal5);",
        "",
        "                                // outter tri vert 3",
        "                                vertexStream.Write(new Vector4(p0, 1));",
        "                                vertexStream.Write(normal5);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv1);",
        "                                vertexStream.Write(tangent5);",
        "                                vertexStream.Write(binormal5);",
        "",
        "                                // inner tri vert 1",
        "                                vertexStream.Write(new Vector4(p8, 1));",
        "                                vertexStream.Write(normal5);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv2);",
        "                                vertexStream.Write(tangent5);",
        "                                vertexStream.Write(binormal5);",
        "",
        "                                // inner tri vert 2",
        "                                vertexStream.Write(new Vector4(p2, 1));",
        "                                vertexStream.Write(normal5);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv0);",
        "                                vertexStream.Write(-tangent4);",
        "                                vertexStream.Write(-binormal4);",
        "",
        "                                // inner tri vert 3",
        "                                vertexStream.Write(new Vector4(p7, 1));",
        "                                vertexStream.Write(-normal4);",
        "                                vertexStream.Write(color);",
        "                                vertexStream.Write(uv3);",
        "                                vertexStream.Write(tangent5);",
        "                                vertexStream.Write(binormal5);",
        "",
        "                                p0 = p7;",
        "                                p2 = p8;",
        "                            }",
        "",
        "                        }",
        "                    }",
        "                }",
        "",
        "                //positionDict.CalcNormals(vertexStream);",
        "",
        "                vertexStream.Position = 0;",
        "",
        "                var vertices = new Buffer(context.D3DDevice, vertexStream, new BufferDescription",
        "                {",
        "                    BindFlags = BindFlags.VertexBuffer,",
        "                    CpuAccessFlags = CpuAccessFlags.None,",
        "                    OptionFlags = ResourceOptionFlags.None,",
        "                    SizeInBytes = streamSize,",
        "                    Usage = ResourceUsage.Default",
        "                });",
        "",
        "                _torus = new Mesh { InputElements = inputElements, Vertices = vertices, NumTriangles = numTriangles, AttributesSize = attributesSize };",
        "            }",
        "",
        "            Changed = false;",
        "        }",
        "",
        "",
        "        private Mesh _torus = new Mesh();",
        "    }",
        "}",
        "",
        "",
        ""
      ],
      "AdditionalAssemblies": []
    }
  ],
  "Operators": [],
  "Connections": [
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "dfb24194-2146-4b22-bbd3-b478a11689e5"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "0767518b-1c4b-4684-9288-f1bb64b8ed55",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "95b7d6f4-9d26-4e73-bf91-5ecafe730fba",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "51a82624-780e-493a-bee0-212892fa4c82",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "bc25d8cd-4410-4c4a-b8f4-c57da2cd5a39",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "74c03208-797f-4636-916e-e8be76e956a9",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "f057490a-68a1-4e23-8b1a-ef406963e66d",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "cd61fd1c-c17d-4fc5-9625-cc343cd4cd34",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "0f95b38c-bcab-42d4-8d5f-02a99d0e7c53",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "cf80c430-56d2-4b25-8f73-c2bce739c08a",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "9c5797a9-1c56-444e-a97d-2f45f5d81977",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "f93bb148-399b-4740-afb3-4d09aa46d999",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "a0790c03-c685-4f6e-a9f7-bf0b6260f830",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "cb909431-6d33-4afb-960f-5d131ac61366",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "41506ab4-0fa9-4724-86ef-82e5e6aa78e4",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b147e0f3-3c06-4953-8a67-fe2251a4024f"
    }
  ]
}