Example #1
0
        protected override void SetOutputs(IGH_DataAccess da)
        {
            outTree = new DataTree <Point3d>();
            GH_Path trunk  = new GH_Path(0); // {0}
            GH_Path branch = new GH_Path();  // {}\
            GH_Path limb   = new GH_Path();


            for (int i = 0; i < particles.Count; i++)
            {
                IQuelea particle = particles[i];
                branch = trunk.AppendElement(i);
                DataTree <Point3d> particlePositionHistoryTree = particle.Position3DHistory.ToTree();

                for (int j = 0; j < particlePositionHistoryTree.BranchCount; j++)
                {
                    limb = branch.AppendElement(j);
                    //for (int k = particlePositionHistoryTree.Branch(j).Count - 1; k >= 0; k--)
                    //{
                    //  outTree.Add(particlePositionHistoryTree.Branch(j)[k], limb);
                    //}
                    outTree.AddRange(particlePositionHistoryTree.Branch(j), limb);
                }
            }
            da.SetDataTree(nextOutputIndex++, outTree);
        }
    protected override void SetOutputs(IGH_DataAccess da)
    {
      outTree = new DataTree<Point3d>();
      GH_Path trunk = new GH_Path(0); // {0}
      GH_Path branch = new GH_Path(); // {}\
      GH_Path limb = new GH_Path();

      
      for (int i = 0; i < particles.Count; i++)
      {
        IQuelea particle = particles[i];
        branch = trunk.AppendElement(i);
        DataTree<Point3d> particlePositionHistoryTree = particle.Position3DHistory.ToTree();

        for (int j = 0; j < particlePositionHistoryTree.BranchCount; j++)
        {
          limb = branch.AppendElement(j);
          //for (int k = particlePositionHistoryTree.Branch(j).Count - 1; k >= 0; k--)
          //{
          //  outTree.Add(particlePositionHistoryTree.Branch(j)[k], limb);
          //}
          outTree.AddRange(particlePositionHistoryTree.Branch(j), limb);
          
        }
      }
      da.SetDataTree(nextOutputIndex++, outTree);
    }
Example #3
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            int iterations = 0;
            var algorithm  = new Boa_Algorithm();
            var inputs     = new double[0];

            if (!GetInputs(DA, ref inputs))
            {
                return;
            }
            if (!DA.GetData(2, ref iterations))
            {
                return;
            }
            GetAlgorithm(DA, ref algorithm);

            if (iterations < 1)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Number of iterations must be greater than or equal to one.");
                return;
            }

            GH_Structure <GH_Number> outputDataTree = new GH_Structure <GH_Number>();
            GH_Path targetPath = DA.ParameterTargetPath(0);

            //Feedback loop
            for (int i = 0; i < iterations; i++)
            {
                // on the first iteration
                if (i == 0)
                {
                    if (!SolveAlgorithm(ref inputs, algorithm))
                    {
                        return;
                    }
                }
                else
                {
                    if (!SolveAlgorithm(ref inputs, algorithm, "Number of outputs is less than number of inputs. Algorithm cannot support a feedback loop."))
                    {
                        return;
                    }
                }

                GH_Number[] outputList = new GH_Number[inputs.Length];

                for (int j = 0; j < inputs.Length; j++)
                {
                    outputList[j] = new GH_Number(inputs[j]);
                }

                outputDataTree.AppendRange(outputList, targetPath.AppendElement(i));
            }

            DA.SetDataTree(0, outputDataTree);
        }
Example #4
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //---- Declareing -------------------------------------------------------------------------------

            GH_Structure <GH_Point> SofistikPts;

            DA.GetDataTree("SofistikPoints", out SofistikPts);

            List <Point3d> flatclean = new List <Point3d>();

            DA.GetDataList <Point3d>("Flatten Points", flatclean);

            DataTree <int> SofistikInt = new DataTree <int>();

            //---- End Declareing ---------------------------------------------------------------------------

            //---- Functions --------------------------------------------------------------------------------

            for (int i = 0; i < flatclean.Count; i++)
            {
                Point3d fpoint = flatclean[i];

                for (int j = 0; j < SofistikPts.Paths.Count; j++)
                {
                    GH_Path pth = SofistikPts.Paths[j];
                    for (int k = 0; k < SofistikPts[pth].Count; k++)
                    {
                        GH_Point ghp = SofistikPts[pth][k];

                        if ((Math.Abs(fpoint.X - ghp.Value.X) <= 0.01) &&
                            (Math.Abs(fpoint.Y - ghp.Value.Y) <= 0.01) &&
                            (Math.Abs(fpoint.Z - ghp.Value.Z) <= 0.01))
                        {
                            SofistikInt.Add(i, pth.AppendElement(k));
                        }
                    }
                }
            }


            //---- End Functions ----------------------------------------------------------------------------

            //---- Set Output -----------------------------------------------------------------------------

            DA.SetDataTree(0, SofistikInt);


            //---- End Set Output -----------------------------------------------------------------------------
        }
Example #5
0
        private static DataTree <Brep> BrepArray2DToDatatree(Brep[][] array)
        {
            DataTree <Brep> tree  = new DataTree <Brep>();
            GH_Path         trunk = new GH_Path();

            for (int i = 0; i < array.Length; i++)
            {
                GH_Path branch = trunk.AppendElement(i);

                for (int j = 0; j < array[i].Length; j++)
                {
                    tree.Add(array[i][j], branch);
                }
            }
            return(tree);
        }
    private static DataTree<Brep> BrepArray2DToDatatree(Brep[][] array)
    {
      DataTree<Brep> tree = new DataTree<Brep>();
      GH_Path trunk = new GH_Path();

      for (int i = 0; i < array.Length; i++)
      {
        GH_Path branch = trunk.AppendElement(i);

        for (int j = 0; j < array[i].Length; j++)
        {
          tree.Add(array[i][j], branch);
        }
      }
      return tree;
    }
        public static bool PtListArrayToGhTreePoint(List <Point3d[]> rhGrid, ref GH_Structure <GH_Point> grid, GH_Path path)
        {
            int num = 0;

            foreach (Point3d[] pointdArray in rhGrid)
            {
                if (pointdArray.Length > 0)
                {
                    List <GH_Point> data = new List <GH_Point>();
                    foreach (Point3d pointd in pointdArray)
                    {
                        data.Add(new GH_Point(pointd));
                    }
                    grid.AppendRange(data, path.AppendElement(num++));
                }
            }
            return(true);
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Surface destination = null;
            double  naN         = double.NaN;
            double  num2        = double.NaN;
            bool    flag        = true;

            if ((((DA.GetData <Surface>(0, ref destination) && DA.GetData <double>(1, ref naN)) && DA.GetData <double>(2, ref num2)) && DA.GetData <bool>(3, ref flag)) && ((destination.IsValid && (naN > 0.0)) && (num2 > 0.0)))
            {
                if (naN > num2)
                {
                    if ((naN % num2) > 0.0)
                    {
                        this.AddRuntimeMessage((GH_RuntimeMessageLevel)1, "One distance parameter needs to be a multiplier of the other");
                        return;
                    }
                }
                else if ((num2 > naN) && ((num2 % naN) > 0.0))
                {
                    this.AddRuntimeMessage((GH_RuntimeMessageLevel)1, "One distance parameter needs to be a multiplier of the other");
                    return;
                }
                List <Point3d[]>        rhGrid = Utility.DivideSurfaceByChordLength(destination, naN, num2, flag, 0.0, 0.0);
                GH_Structure <GH_Point> grid   = new GH_Structure <GH_Point>();
                GH_Path path = new GH_Path(DA.ParameterTargetPath(0));
                path = path.AppendElement(DA.ParameterTargetIndex(0));
                if (!PtListArrayToGhTreePoint(rhGrid, ref grid, path))
                {
                    this.AddRuntimeMessage((GH_RuntimeMessageLevel)1, "Failed to convert Rhino list array to GH tree.");
                }
                else
                {
                    DA.SetDataTree(0, grid);
                }
            }
        }
Example #9
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            string        ID      = this.Attributes.InstanceGuid.ToString();
            string        name    = new GUIDtoAlpha(Convert.ToString(ID + Convert.ToString(this.RunCount)), false).Text;
            List <string> newKeys = new List <string>();

            string type, format;
            GH_Structure <IGH_Goo> El;
            GH_Structure <IGH_Goo> OutPut = new GH_Structure <IGH_Goo>();

            if (!DA.GetDataTree(0, out El))
            {
                return;
            }

            for (int i = 0; i < El.Paths.Count; i++)
            {
                GH_Path Q = El.get_Path(i);
                GH_Path P = El.get_Path(i);
                P.AppendElement(0);
                for (int k = 0; k < El.get_Branch(Q).Count; k++)
                {
                    IGH_Goo X = El.get_DataItem(Q, k);


                    wObject W;
                    X.CastTo(out W);

                    format = W.Type;

                    if (format == "Parrot")
                    {
                        pElement E;
                        E = (pElement)W.Element;

                        type = E.Type;
                        newKeys.Add(E.Element.Name);

                        switch (type)
                        {
                        case ("Button"):
                            Button C0 = (Button)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C0.PreviewMouseDown -= (o, e) => { ExpireSolution(true); };
                                C0.PreviewMouseDown += (o, e) => { ExpireSolution(true); };

                                C0.PreviewMouseUp -= (o, e) => { ExpireSolution(true); };
                                C0.PreviewMouseUp += (o, e) => { ExpireSolution(true); };
                            }

                            OutPut.Append(new GH_ObjectWrapper((Mouse.LeftButton == MouseButtonState.Pressed) & C0.IsMouseOver), P);
                            break;

                        case ("Calculator"):
                            Calculator C1 = (Calculator)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C1.ValueChanged -= (o, e) => { ExpireSolution(true); };
                                C1.ValueChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C1.Value), P);
                            break;

                        case ("Calendar"):
                            Calendar C2 = (Calendar)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C2.SelectedDatesChanged -= (o, e) => { ExpireSolution(true); };
                                C2.SelectedDatesChanged += (o, e) => { ExpireSolution(true); };
                            }
                            List <IGH_Goo> Dates = new List <IGH_Goo>();

                            for (int j = 0; j < C2.SelectedDates.Count; j++)
                            {
                                OutPut.Append(new GH_ObjectWrapper(C2.SelectedDates[j]), P);
                            }
                            break;

                        case ("Clock"):
                            Clock C23 = (Clock)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C23.LayoutUpdated -= (o, e) => { ExpireSolution(true); };
                                C23.LayoutUpdated += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C23.Time), P);
                            break;

                        case ("CheckBox"):
                            CheckBox C19 = (CheckBox)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C19.Click -= (o, e) => { ExpireSolution(true); };
                                C19.Click += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C19.IsChecked), P);
                            break;

                        case ("CheckListBox"):
                            CheckListBox C3 = (CheckListBox)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C3.ItemSelectionChanged -= (o, e) => { ExpireSolution(true); };
                                C3.ItemSelectionChanged += (o, e) => { ExpireSolution(true); };
                            }
                            for (int j = 0; j < C3.SelectedItems.Count; j++)
                            {
                                OutPut.Append(new GH_ObjectWrapper(C3.SelectedItems[j]), P);
                            }
                            break;

                        case ("ColorCanvas"):
                            ColorCanvas C4 = (ColorCanvas)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C4.SelectedColorChanged -= (o, e) => { ExpireSolution(true); };
                                C4.SelectedColorChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(new wColor((System.Windows.Media.Color)C4.SelectedColor).ToDrawingColor()), P);
                            OutPut.Append(new GH_ObjectWrapper(C4.SelectedColor), P);
                            break;

                        case ("ColorPicker"):
                            ColorPicker C5 = (ColorPicker)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C5.SelectedColorChanged -= (o, e) => { ExpireSolution(true); };
                                C5.SelectedColorChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(new wColor((System.Windows.Media.Color)C5.SelectedColor).ToDrawingColor()), P);
                            break;

                        case ("CheckComboBox"):
                            CheckComboBox C6 = (CheckComboBox)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C6.ItemSelectionChanged -= (o, e) => { ExpireSolution(true); };
                                C6.ItemSelectionChanged += (o, e) => { ExpireSolution(true); };
                            }
                            for (int j = 0; j < C6.SelectedItems.Count; j++)
                            {
                                OutPut.Append(new GH_ObjectWrapper(C6.SelectedItems[j]), P);
                            }
                            break;

                        case ("RangeSlider"):
                            MahApps.Metro.Controls.RangeSlider C7 = (MahApps.Metro.Controls.RangeSlider)E.Layout.Children[0];
                            if (!keys.Contains(E.Element.Name))
                            {
                                C7.UpperValueChanged -= (o, e) => { ExpireSolution(true); };
                                C7.UpperValueChanged += (o, e) => { ExpireSolution(true); };
                                C7.LowerValueChanged -= (o, e) => { ExpireSolution(true); };
                                C7.LowerValueChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(new Interval(C7.LowerValue, C7.UpperValue)), P);
                            break;

                        case ("Slider"):
                            Slider C8 = (Slider)E.Layout.Children[0];
                            if (!keys.Contains(E.Element.Name))
                            {
                                C8.ValueChanged -= (o, e) => { ExpireSolution(true); };
                                C8.ValueChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C8.Value), P);
                            break;

                        case ("RadioButton"):
                            RadioButton C9 = (RadioButton)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C9.Checked -= (o, e) => { ExpireSolution(true); };
                                C9.Checked += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C9.IsChecked), P);
                            break;

                        case ("TimePicker"):
                            MaterialDesignThemes.Wpf.TimePicker C10 = (MaterialDesignThemes.Wpf.TimePicker)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C10.MouseUp       -= (o, e) => { ExpireSolution(true); };
                                C10.MouseUp       += (o, e) => { ExpireSolution(true); };
                                C10.LayoutUpdated -= (o, e) => { ExpireSolution(true); };
                                C10.LayoutUpdated += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C10.SelectedTime), P);
                            break;

                        case ("PickDate"):
                            DatePicker C11 = (DatePicker)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C11.SelectedDateChanged -= (o, e) => { ExpireSolution(true); };
                                C11.SelectedDateChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C11.SelectedDate), P);
                            break;

                        case ("PickDateTime"):
                            DateTimePicker C12 = (DateTimePicker)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C12.ValueChanged -= (o, e) => { ExpireSolution(true); };
                                C12.ValueChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C12.Value), P);
                            break;

                        case ("ListView"):
                            ListView C13 = (ListView)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C13.SelectionChanged -= (o, e) => { ExpireSolution(true); };
                                C13.SelectionChanged += (o, e) => { ExpireSolution(true); };
                            }
                            for (int j = 0; j < C13.Items.Count; j++)
                            {
                                Label tbox = (Label)C13.Items[j];

                                OutPut.Append(new GH_ObjectWrapper(tbox.ToolTip.ToString()), P);
                            }
                            break;

                        case ("ListBox"):
                            ListBox C14 = (ListBox)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C14.SelectionChanged -= (o, e) => { ExpireSolution(true); };
                                C14.SelectionChanged += (o, e) => { ExpireSolution(true); };
                            }
                            for (int j = 0; j < C14.SelectedItems.Count; j++)
                            {
                                OutPut.Append(new GH_ObjectWrapper(C14.SelectedItems[j]), P);
                            }
                            break;

                        case ("ComboBox"):
                            ComboBox C15 = (ComboBox)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C15.SelectionChanged -= (o, e) => { ExpireSolution(true); };
                                C15.SelectionChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C15.SelectedValue), P);
                            break;

                        case ("ScrollValue"):
                            ButtonSpinner C16 = (ButtonSpinner)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C16.Spin -= (o, e) => { ExpireSolution(true); };
                                C16.Spin += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C16.Content), P);
                            break;

                        case ("ScrollNumber"):
                            NumericUpDown C17 = (NumericUpDown)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C17.ValueChanged -= (o, e) => { ExpireSolution(true); };
                                C17.ValueChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C17.Value), P);
                            break;

                        case ("TextBox"):
                            TextBox C18 = (TextBox)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C18.TextChanged -= (o, e) => { ExpireSolution(true); };
                                C18.TextChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C18.Text), P);
                            break;

                        case ("TreeView"):
                            TreeView C20 = (TreeView)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C20.SelectedItemChanged -= (o, e) => { ExpireSolution(true); };
                                C20.SelectedItemChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C20.SelectedValue), P);
                            break;

                        case ("GridView"):
                            ListView C21 = (ListView)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C21.SelectionChanged -= (o, e) => { ExpireSolution(true); };
                                C21.SelectionChanged += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C21.Items), P);
                            break;

                        case ("Toggle"):
                            ToggleButton C22 = (ToggleButton)E.Element;
                            if (!keys.Contains(E.Element.Name))
                            {
                                C22.Click -= (o, e) => { ExpireSolution(true); };
                                C22.Click += (o, e) => { ExpireSolution(true); };
                            }
                            OutPut.Append(new GH_ObjectWrapper(C22.IsChecked), P);
                            break;
                        }
                    }
                }
            }

            keys = newKeys;

            DA.SetDataTree(0, OutPut);
            DA.SetDataList(1, keys);
        }
Example #10
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            GH_Structure <GH_Point>  points  = new GH_Structure <GH_Point>();
            GH_Structure <GH_Number> indices = new GH_Structure <GH_Number>();
            GH_Structure <IGH_Goo>   fTrees  = new GH_Structure <IGH_Goo>();

            if (!DA.GetDataTree(0, out points))
            {
                return;
            }
            if (!DA.GetDataTree(1, out indices))
            {
                return;
            }
            if (!DA.GetDataTree(2, out fTrees))
            {
                return;
            }

            GH_Structure <GH_Point>   foundPts = new GH_Structure <GH_Point>();
            GH_Structure <GH_Integer> foundInd = new GH_Structure <GH_Integer>();

            for (int i = 0; i < points.PathCount; i++)
            {
                GH_Path        path      = points.Paths[i];
                List <IGH_Goo> fTreeList = fTrees.Branches[fTrees.PathCount < i ? fTrees.PathCount - 1 : i];
                if (fTreeList.Count == 0)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No RTree for branch" + points.Paths[i].ToString());
                    return;
                }
                if (fTreeList.Count > 1)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Multiple RTrees for branch" + points.Paths[i].ToString() + "to search multiple RTrees place them in individual branches");
                    return;
                }
                froGHRTree       fTree   = ((GH_froGHRTree)fTreeList[0]).Value;
                List <GH_Number> indList = indices.Branches[indices.PathCount < i ? indices.PathCount - 1 : i];
                int count = 0;
                foreach (GH_Point ghP in points.Branches[i])
                {
                    GH_Path foundPath = path.AppendElement(count);
                    // perform search
                    List <int> fIndices = fTree.IndicesInSphere(ghP.Value, indList[indList.Count > count ? count : indList.Count - 1].Value);
                    if (fIndices.Count == 0)
                    {
                        foundPts.AppendRange(new List <GH_Point>(), foundPath);
                        foundInd.AppendRange(new List <GH_Integer>(), foundPath);
                    }
                    else
                    {
                        foreach (int item2 in fIndices)
                        {
                            foundPts.Append(new GH_Point(fTree.Points[item2]), foundPath);
                            foundInd.Append(new GH_Integer(item2), foundPath);
                        }
                    }

                    count++;
                }
            }
            DA.SetDataTree(0, foundPts);
            DA.SetDataTree(1, foundInd);
        }
Example #11
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //declare input variables to load into

            AuthToken authToken = new AuthToken();
            string sheetName = "";
            string worksheet = "";
            bool includeBlankCells = false;
            bool rangeSpecified = false;
            SpreadsheetRange range = new SpreadsheetRange();
            bool rowsColumns = false;
            bool formulasValues = false;

            //declare output variables
            List<string> metaData = new List<string>();
            GH_Structure<GH_String> values = new GH_Structure<GH_String>();
            GH_Structure<GH_String> addresses = new GH_Structure<GH_String>();

            //get data from inputs
            if (!DA.GetData<AuthToken>("Token", ref authToken))
            {
                return; //exit if no token
            }
            if (!authToken.IsValid)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The provided authentication token appears to be invalid. Try re-running the Google Authenticator component.");
                return; //exit if invalid token
            }

            if (!DA.GetData<string>("Name", ref sheetName))
            {
                return; //exit if no name provided
            }
            DA.GetData<string>("Worksheet", ref worksheet);
            DA.GetData<bool>("Include Blank Cells?", ref includeBlankCells);
            if (DA.GetData<SpreadsheetRange>("Spreadsheet Range", ref range))
            {
                rangeSpecified = true;
            }
            DA.GetData<bool>("Organize by Rows or Columns", ref rowsColumns);
            DA.GetData<bool>("Read Formulas or Values", ref formulasValues);

            //set up oAuth parameters
            OAuth2Parameters parameters = GDriveUtil.GetParameters(authToken);
            //establish spreadsheetservice
            SpreadsheetsService service = GDriveUtil.GetSpreadsheetsService(parameters);
            //get spreadsheet by name
            SpreadsheetEntry spreadsheet = GDriveUtil.findSpreadsheetByName(sheetName, service);

            if (spreadsheet == null)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Specified Spreadsheet not found.");
                return;
            }

            //gather spreadsheet metadata
            metaData.Add("Spreadsheet Name: " + spreadsheet.Title.Text);
            metaData.Add("Last Updated: " + spreadsheet.Updated.ToString());
            metaData.Add("Worksheets: " + worksheetList(spreadsheet.Worksheets));

            //find the specified worksheet, or first one if none specified
            WorksheetEntry worksheetEntry = null;
            worksheetEntry = GDriveUtil.findWorksheetByName(worksheet, spreadsheet);

            if (worksheetEntry == null)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Specified worksheet not found.");
                return;
            }

            // Fetch the cell feed of the worksheet.
            CellQuery cellQuery = new CellQuery(worksheetEntry.CellFeedLink);
            if (rangeSpecified)
            {
                if (range.TestValid())
                {
                    cellQuery.MinimumColumn = range.startColumn();
                    cellQuery.MinimumRow = range.startRow();
                    cellQuery.MaximumColumn = range.endColumn();
                    cellQuery.MaximumRow = range.endRow();
                }
                else
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid Range Specified");
                    return;
                }
            }

            //passes null values if user wants the blank cells represented, otherwise they are omitted from output.
            if (includeBlankCells)
            {
                cellQuery.ReturnEmpty = ReturnEmptyCells.yes;
            }
            //set up cell feed
            CellFeed cellFeed = service.Query(cellQuery);

            foreach (CellEntry cell in cellFeed.Entries) //for all the cells in the feed
            {

                GH_Path path = new GH_Path(DA.Iteration); //set up data path for data tree
                uint e = (rowsColumns) ? cell.Row : cell.Column; //decide whether to structure data path by row or column
                path = path.AppendElement((int)e);

                string v = (formulasValues) ? cell.InputValue : cell.Value; //decide whether to get the cell formula or the cell value as output
                values.Append(new GH_String(v), path); //save the value of the cell

                addresses.Append(new GH_String(cell.Title.Text), path); // save the address of the cell
            }

            //set output data
            DA.SetDataTree(0, values);
            DA.SetDataTree(1, addresses);
            DA.SetDataList("Sheet Info", metaData);
        }
        // dual loop not directly connected to plates
        private void half_dualLoop_type_2(int edgeIndex, int triangleIndex, int neighbourTriIndex)
        {
            GH_Path path = new GH_Path(triangleIndex);

            Edge edge = iSpringMesh.Edges[edgeIndex];

            // added for recognizing where is the plate - plate id
            int occupyiedVertex = edge.FirstAdjacentVertexIndex;
            if (iVertexStatus[edge.FirstAdjacentVertexIndex]) { occupyiedVertex = edge.FirstAdjacentVertexIndex; }
            if (edge.SecondAdjacentVertexIndex > 0 && iVertexStatus[edge.SecondAdjacentVertexIndex]) { occupyiedVertex = edge.SecondAdjacentVertexIndex; }
            int plateID = iPolyLineID[occupyiedVertex];
            plateID = -10 - plateID;

            // vertex point
            int vertex1 = edge.FirstVertexIndex;
            int vertex2 = edge.SecondVertexIndex;

            Point3d vertexPt1 = iSpringMesh.Vertices[vertex1].Position;
            Point3d vertexPt2 = iSpringMesh.Vertices[vertex2].Position;

            double scaler1 = curveVerticesValues[vertex1];
            double scaler2 = curveVerticesValues[vertex2];

            double planarOffset1 = planarVerticesValues[vertex1];
            double planarOffset2 = planarVerticesValues[vertex2];

            double openingScalar1 = openingWidthVerticesValues[vertex1];
            double openingScalar2 = openingWidthVerticesValues[vertex2];

            double curvePointiness1 = pointinessValues[vertex1];
            double curvePointiness2 = pointinessValues[vertex2];

            //---- TriLoop Side UP -----------------------------------------------
            #region TriLoop Side UP

            Point3d vertexPtUp1 = topCps[vertex1];
            Point3d vertexPtUp2 = topCps[vertex2];
            Point3d vertexPtUpM = 0.5 * (vertexPtUp1 + vertexPtUp2);

            Vector3d v_vertexPtUp1 = vertexPtUp1 - vertexPtUpM;
            Vector3d v_vertexPtUp2 = vertexPtUp2 - vertexPtUpM;
            v_vertexPtUp1.Unitize();
            v_vertexPtUp2.Unitize();

            Point3d oVertexPtUpM1 = vertexPtUpM + (v_vertexPtUp1 * planarOffset1);
            Point3d oVertexPtUpM2 = vertexPtUpM + (v_vertexPtUp2 * planarOffset2);

            Point3d ctPtUp1 = (scaler1) * vertexPtUp1 + (1 - scaler1) * oVertexPtUpM1;
            Point3d ctPtUp2 = (scaler2) * vertexPtUp2 + (1 - scaler2) * oVertexPtUpM2;

            // normalise hohles
            Point3d openingCtPtUp1 = vertexPtUp1 + (openingScalar1 * v_vertexPtUp1 * -1);
            Point3d openingCtPtUp2 = vertexPtUp2 + (openingScalar2 * v_vertexPtUp2 * -1);

            if (new Vector3d(ctPtUp1 - vertexPtUp1).Length > openingScalar1)
                ctPtUp1 = openingCtPtUp1;

            if (new Vector3d(ctPtUp2 - vertexPtUp2).Length > openingScalar2)
                ctPtUp2 = openingCtPtUp2;
            // end normalise hohles

            #endregion TriLoop Side UP

            //---- TriLoop Side Down -----------------------------------------------
            #region TriLoop Side Down
            Point3d vertexPtDown1 = bottomCps[vertex1];
            Point3d vertexPtDown2 = bottomCps[vertex2];
            Point3d vertexPtDownM = 0.5 * (vertexPtDown1 + vertexPtDown2);

            Vector3d v_vertexPtDown1 = vertexPtDown1 - vertexPtDownM;
            Vector3d v_vertexPtDown2 = vertexPtDown2 - vertexPtDownM;
            v_vertexPtDown1.Unitize();
            v_vertexPtDown2.Unitize();

            Point3d oVertexPtDownM1 = vertexPtDownM + (v_vertexPtDown1 * planarOffset1);
            Point3d oVertexPtDownM2 = vertexPtDownM + (v_vertexPtDown2 * planarOffset2);

            Point3d ctPtDown1 = (scaler1) * vertexPtDown1 + (1 - scaler1) * oVertexPtDownM1;
            Point3d ctPtDown2 = (scaler2) * vertexPtDown2 + (1 - scaler2) * oVertexPtDownM2;

            // normalise hohles
            Point3d openingCtPtDown1 = vertexPtDown1 + (openingScalar1 * v_vertexPtDown1 * -1);
            Point3d openingCtPtDown2 = vertexPtDown2 + (openingScalar2 * v_vertexPtDown2 * -1);

            if (new Vector3d(ctPtDown1 - vertexPtDown1).Length > openingScalar1)
                ctPtDown1 = openingCtPtDown1;

            if (new Vector3d(ctPtDown2 - vertexPtDown2).Length > openingScalar2)
                ctPtDown2 = openingCtPtDown2;
            // end normalise hohles

            #endregion TriLoop Side Down

            //---- Plate Side UP -------------------------------------------------
            #region Plate Side UP
            Point3d upTPI = topCenterPts[triangleIndex];

            Vector3d v_vertexPtUp1_upTPI = vertexPtUp1 - upTPI;
            Vector3d v_vertexPtUp2_upTPI = vertexPtUp2 - upTPI;
            v_vertexPtUp1_upTPI.Unitize();
            v_vertexPtUp2_upTPI.Unitize();

            Point3d oUpTPI01 = upTPI + (v_vertexPtUp1_upTPI * planarOffset1);
            Point3d oUpTPI02 = upTPI + (v_vertexPtUp2_upTPI * planarOffset2);

            Point3d ctUpTPI1 = (scaler1) * vertexPtUp1 + (1 - scaler1) * oUpTPI01;
            Point3d ctUpTPI2 = (scaler2) * vertexPtUp2 + (1 - scaler2) * oUpTPI02;

            // normalise hohles
            Point3d openingCtUpTPI1 = vertexPtUp1 + (openingScalar1 * v_vertexPtUp1_upTPI * -1);
            Point3d openingCtUpTPI2 = vertexPtUp2 + (openingScalar2 * v_vertexPtUp2_upTPI * -1);

            if (new Vector3d(ctUpTPI1 - vertexPtUp1).Length > openingScalar1)
                ctUpTPI1 = openingCtUpTPI1;

            if (new Vector3d(ctUpTPI2 - vertexPtUp2).Length > openingScalar2)
                ctUpTPI2 = openingCtUpTPI2;
            // end normalise hohles

            #endregion Plate Side UP

            //---- Plate Side DOWN -----------------------------------------------
            #region Plate Side DOWN
            Point3d downTPI = bottomCenterPts[triangleIndex];

            Vector3d v_vertexPtUp1_downTPI = vertexPtDown1 - downTPI;
            Vector3d v_vertexPtUp2_downTPI = vertexPtDown2 - downTPI;
            v_vertexPtUp1_downTPI.Unitize();
            v_vertexPtUp2_downTPI.Unitize();

            Point3d oDownTPI01 = downTPI + (v_vertexPtUp1_downTPI * planarOffset1);
            Point3d oDownTPI02 = downTPI + (v_vertexPtUp2_downTPI * planarOffset2);

            Point3d ctDownTPI1 = (scaler1) * vertexPtDown1 + (1 - scaler1) * oDownTPI01;
            Point3d ctDownTPI2 = (scaler2) * vertexPtDown2 + (1 - scaler2) * oDownTPI02;

            // normalise hohles
            Point3d openingCtDownTPI1 = vertexPtDown1 + (openingScalar1 * v_vertexPtUp1_downTPI * -1);
            Point3d openingCtDownTPI2 = vertexPtDown2 + (openingScalar2 * v_vertexPtUp2_downTPI * -1);

            if (new Vector3d(ctDownTPI1 - vertexPtDown1).Length > openingScalar1)
                ctDownTPI1 = openingCtDownTPI1;

            if (new Vector3d(ctDownTPI2 - vertexPtDown2).Length > openingScalar2)
                ctDownTPI2 = openingCtDownTPI2;
            // end normalise hohles

            #endregion Plate Side DOWN

            //---- Curves Right 1 -----------------------------------------------------------
            #region Curves Right 1

            // Pointiness of the Surface
            Point3d min_vertexPtRight1 = 0.5 * (ctUpTPI1 + ctDownTPI1);
            Point3d vertexPtRight1 = (curvePointiness1 * vertexPt1) + ((1 - curvePointiness1) * min_vertexPtRight1);

            Curve right1Loop = Curve.CreateControlPointCurve(
                new List<Point3d>() { oDownTPI01, ctDownTPI1, vertexPtRight1, ctUpTPI1, oUpTPI01 }, curveDegree);

            Curve right1PlanarUp = Curve.CreateControlPointCurve(
                new List<Point3d>() { oUpTPI01, upTPI }, 1);

            Curve right1PlanarDown = Curve.CreateControlPointCurve(
                new List<Point3d>() { downTPI, oDownTPI01 }, 1);
            /*
            PolyCurve right1 = new PolyCurve();
            right1.Append(right1PlanarUp);
            right1.Append(right1Loop);
            right1.Append(right1PlanarDown);*/
            Curve right1 = Curve.JoinCurves(new List<Curve>() { right1PlanarDown, right1Loop, right1PlanarUp }, documentTolerance, true)[0];

            if (iPolySrf)
            {
                right1 = right1Loop;
            }

            #endregion Curves Right 1

            //---- Curves Left 1 -----------------------------------------------------------
            #region Curves Left 1

            // Pointiness of the Surface
            Point3d min_vertexPtLeft1 = 0.5 * (ctPtUp1 + ctPtDown1);
            Point3d vertexPtLeft1 = (curvePointiness1 * vertexPt1) + ((1 - curvePointiness1) * min_vertexPtLeft1);

            Curve left1Loop = Curve.CreateControlPointCurve(
                new List<Point3d>() { oVertexPtDownM1, ctPtDown1, vertexPtLeft1, ctPtUp1, oVertexPtUpM1 }, curveDegree);

            Curve left1PlanarUp = Curve.CreateControlPointCurve(
                new List<Point3d>() { oVertexPtUpM1, vertexPtUpM }, 1);

            Curve left1PlanarDown = Curve.CreateControlPointCurve(
                new List<Point3d>() { vertexPtDownM, oVertexPtDownM1 }, 1);

            /*
            PolyCurve left1 = new PolyCurve();
            left1.Append(left1PlanarUp);
            left1.Append(left1Loop);
            left1.Append(left1PlanarDown);*/
            Curve left1 = Curve.JoinCurves(new List<Curve>() { left1PlanarDown, left1Loop, left1PlanarUp }, documentTolerance, true)[0];

            if (iPolySrf)
            {
                left1 = left1Loop;
            }

            #endregion Curves Left 1

            //---- Curves Right 2 -----------------------------------------------------------
            #region Curves Right 2

            // Pointiness of the Surface
            Point3d min_vertexPtRight2 = 0.5 * (ctUpTPI2 + ctDownTPI2);
            Point3d vertexPtRight2 = (curvePointiness2 * vertexPt2) + ((1 - curvePointiness2) * min_vertexPtRight2);

            Curve right2Loop = Curve.CreateControlPointCurve(
                new List<Point3d>() { oDownTPI02, ctDownTPI2, vertexPtRight2, ctUpTPI2, oUpTPI02 }, curveDegree);

            Curve right2PlanarUp = Curve.CreateControlPointCurve(
                new List<Point3d>() { oUpTPI02, upTPI }, 1);

            Curve right2PlanarDown = Curve.CreateControlPointCurve(
                new List<Point3d>() { downTPI, oDownTPI02 }, 1);

            /*
            PolyCurve right2 = new PolyCurve();
            right2.Append(right2PlanarUp);
            right2.Append(right2Loop);
            right2.Append(right2PlanarDown);*/
            Curve right2 = Curve.JoinCurves(new List<Curve>() { right2PlanarDown, right2Loop, right2PlanarUp }, documentTolerance, true)[0];

            if (iPolySrf)
            {
                right2 = right2Loop;
            }

            #endregion Curves Right 2

            //---- Curves Left 2 -----------------------------------------------------------
            #region Curves Left 2

            // Pointiness of the Surface
            Point3d min_vertexPtLeft2 = 0.5 * (ctPtUp2 + ctPtDown2);
            Point3d vertexPtLeft2 = (curvePointiness2 * vertexPt2) + ((1 - curvePointiness2) * min_vertexPtLeft2);

            Curve left2Loop = Curve.CreateControlPointCurve(
                new List<Point3d>() { oVertexPtDownM2, ctPtDown2, vertexPtLeft2, ctPtUp2, oVertexPtUpM2 }, curveDegree);

            Curve left2PlanarUp = Curve.CreateControlPointCurve(
                new List<Point3d>() { oVertexPtUpM2, vertexPtUpM }, 1);

            Curve left2PlanarDown = Curve.CreateControlPointCurve(
                new List<Point3d>() { vertexPtDownM, oVertexPtDownM2 }, 1);

            /*
            PolyCurve left2 = new PolyCurve();
            left2.Append(left2PlanarUp);
            left2.Append(left2Loop);
            left2.Append(left2PlanarDown);*/
            Curve left2 = Curve.JoinCurves(new List<Curve>() { left2PlanarDown, left2Loop, left2PlanarUp }, documentTolerance, true)[0];

            if (iPolySrf)
            {
                left2 = left2Loop;
            }

            #endregion Curves Left 2

            // sorting sequence

            Brep[] brep1 = Brep.CreateFromLoft(
                       new List<Curve>() { left1, right1 },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       );

            #region allow poly surface
            if (iPolySrf)
            {
                Brep[] brep1PlanarUp = Brep.CreateFromLoft(
                    new List<Curve>() { left1PlanarUp, right1PlanarUp },
                    Point3d.Unset, Point3d.Unset,
                    LoftType.Normal, false
                    );

                Brep[] brep1PlanarDown = Brep.CreateFromLoft(
                    new List<Curve>() { left1PlanarDown, right1PlanarDown },
                    Point3d.Unset, Point3d.Unset,
                    LoftType.Normal, false
                    );

                brep1 = Brep.JoinBreps(new List<Brep>(){brep1PlanarDown[0], brep1[0], brep1PlanarUp[0]}, documentTolerance);
            }
            #endregion allow poly surface

            if (brep1.Length > 0)
            {
                //oDualLoop.Add(brep1[0]);
                Brep brepTestNormal = brep1[0];
                BrepFace brepF = brepTestNormal.Faces[0];

                // id
                int neighbour2TriIndex = 0;
                if (vertex2 == iSpringMesh.Triangles[triangleIndex].FirstVertexIndex)
                    neighbour2TriIndex = iSpringMesh.Triangles[triangleIndex].FirstAdjTriIndex;
                if (vertex2 == iSpringMesh.Triangles[triangleIndex].SecondVertexIndex)
                    neighbour2TriIndex = iSpringMesh.Triangles[triangleIndex].SecondAdjTriIndex;
                if (vertex2 == iSpringMesh.Triangles[triangleIndex].ThirdVertexIndex)
                    neighbour2TriIndex = iSpringMesh.Triangles[triangleIndex].ThirdAdjTriIndex;

                if (brepF.NormalAt(0, 0).Z < 0)  // conditional flipping surface, according face normal. special case for our pavilion mesh
                {
                    Brep[] brepN1 = Brep.CreateFromLoft(
                       new List<Curve>() { right1, left1 },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       );

                    #region allow poly surface
                    if (iPolySrf)
                    {
                        Brep[] brepN1PlanarUp = Brep.CreateFromLoft(
                            new List<Curve>() { right1PlanarUp, left1PlanarUp },
                            Point3d.Unset, Point3d.Unset,
                            LoftType.Normal, false
                            );

                        Brep[] brepN1PlanarDown = Brep.CreateFromLoft(
                            new List<Curve>() { right1PlanarDown, left1PlanarDown },
                            Point3d.Unset, Point3d.Unset,
                            LoftType.Normal, false
                            );

                        brepN1 = Brep.JoinBreps(new List<Brep>() { brepN1PlanarDown[0], brepN1[0], brepN1PlanarUp[0] }, documentTolerance);
                    }
                    #endregion allow poly surface

                    if (brep1.Length > 0)
                    {
                        oDualLoop2.Add(brepN1[0], path.AppendElement(0));
                        oDualLoop2ID.Add("J;" + triangleIndex.ToString() + ";" + neighbourTriIndex.ToString() + ";" + neighbour2TriIndex.ToString() + ";" + plateID.ToString(), path.AppendElement(0));

                        oDualLoop2Curves.Add(right1, path.AppendElement(0));
                        oDualLoop2Curves.Add(left1, path.AppendElement(0));
                    }
                }
                else
                {
                    oDualLoop2.Add(brep1[0], path.AppendElement(0));
                    oDualLoop2ID.Add("J;" + triangleIndex.ToString() + ";" + neighbourTriIndex.ToString() + ";" + neighbour2TriIndex.ToString() + ";" + plateID.ToString(), path.AppendElement(0));

                    oDualLoop2Curves.Add(left1, path.AppendElement(0));
                    oDualLoop2Curves.Add(right1, path.AppendElement(0));
                }
            }

            Brep[] brep2 = Brep.CreateFromLoft(
                       new List<Curve>() { left2, right2 },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       );

            #region allow poly surface
            if (iPolySrf)
            {
                Brep[] brep2PlanarUp = Brep.CreateFromLoft(
                    new List<Curve>() { left2PlanarUp, right2PlanarUp },
                    Point3d.Unset, Point3d.Unset,
                    LoftType.Normal, false
                    );

                Brep[] brep2PlanarDown = Brep.CreateFromLoft(
                    new List<Curve>() { left2PlanarDown, right2PlanarDown },
                    Point3d.Unset, Point3d.Unset,
                    LoftType.Normal, false
                    );

                brep2 = Brep.JoinBreps(new List<Brep>() { brep2PlanarDown[0], brep2[0], brep2PlanarUp[0] }, documentTolerance);
            }
            #endregion allow poly surface

            if (brep2.Length > 0)
            {
                //oDualLoop.Add(brep2[0]);
                Brep brepTestNormal = brep2[0];
                BrepFace brepF = brepTestNormal.Faces[0];

                // id
                int neighbour2TriIndex = 0;
                if (vertex1 == iSpringMesh.Triangles[triangleIndex].FirstVertexIndex)
                    neighbour2TriIndex = iSpringMesh.Triangles[triangleIndex].FirstAdjTriIndex;
                if (vertex1 == iSpringMesh.Triangles[triangleIndex].SecondVertexIndex)
                    neighbour2TriIndex = iSpringMesh.Triangles[triangleIndex].SecondAdjTriIndex;
                if (vertex1 == iSpringMesh.Triangles[triangleIndex].ThirdVertexIndex)
                    neighbour2TriIndex = iSpringMesh.Triangles[triangleIndex].ThirdAdjTriIndex;

                if (brepF.NormalAt(0, 0).Z < 0)
                {
                    Brep[] brepN2 = Brep.CreateFromLoft(
                       new List<Curve>() { right2, left2 },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       );

                    #region allow poly surface
                    if (iPolySrf)
                    {
                        Brep[] brepN2PlanarUp = Brep.CreateFromLoft(
                            new List<Curve>() { right2PlanarUp, left2PlanarUp },
                            Point3d.Unset, Point3d.Unset,
                            LoftType.Normal, false
                            );

                        Brep[] brepN2PlanarDown = Brep.CreateFromLoft(
                            new List<Curve>() { right2PlanarDown, left2PlanarDown },
                            Point3d.Unset, Point3d.Unset,
                            LoftType.Normal, false
                            );

                        brepN2 = Brep.JoinBreps(new List<Brep>() { brepN2PlanarDown[0], brepN2[0], brepN2PlanarUp[0] }, documentTolerance);
                    }
                    #endregion allow poly surface

                    if (brep2.Length > 0)
                    {
                        oDualLoop2.Add(brepN2[0], path.AppendElement(1));
                        oDualLoop2ID.Add("J;" + triangleIndex.ToString() + ";" + neighbourTriIndex.ToString() + ";" + neighbour2TriIndex.ToString() + ";" + plateID.ToString(), path.AppendElement(1));

                        oDualLoop2Curves.Add(right2, path.AppendElement(1));
                        oDualLoop2Curves.Add(left2, path.AppendElement(1));
                    }
                }
                else
                {
                    oDualLoop2.Add(brep2[0], path.AppendElement(1));
                    oDualLoop2ID.Add("J;" + triangleIndex.ToString() + ";" + neighbourTriIndex.ToString() + ";" + neighbour2TriIndex.ToString() + ";" + plateID.ToString(), path.AppendElement(1));

                    oDualLoop2Curves.Add(left2, path.AppendElement(1));
                    oDualLoop2Curves.Add(right2, path.AppendElement(1));
                }
            }
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //---- Declareing ---------------------------------------------------------------------------

            List<Tri_Loop_Component> All_Components = new List<Tri_Loop_Component>();
            DA.GetDataList<Tri_Loop_Component>("Components", All_Components);

            DataTree<Point3d> SofistikPoints = new DataTree<Point3d>();
            DataTree<int> SofistikIndexies = new DataTree<int>();

            DataTree<int> SofistikCrvPtIdx = new DataTree<int>();
            DataTree<Point3d> SofistikCrvPtCoo = new DataTree<Point3d>();

            DataTree<Brep> SofistikBreps = new DataTree<Brep>();
            DataTree<int> SofistikBrepsIdx = new DataTree<int>();

            DataTree<Curve> SofistikCurves = new DataTree<Curve>();

            //---- End Declareing -----------------------------------------------------------------------

            //---- Functions ----------------------------------------------------------------------------

            int componentIdx = 0;

            foreach (Tri_Loop_Component component in All_Components)
            {
                GH_Path pth1 = new GH_Path(componentIdx);

                // run / generate Informations for Sofistik
                component.SofistikInformation();
                component.SofistikCreateSurfaces();

                // Points
                for (int j = 0; j < component.SofistikPlatePoints.BranchCount; j++)
                {

                    foreach (Point3d p in component.SofistikPlatePoints.Branch(j))
                    { SofistikPoints.Add(p, pth1.AppendElement(j)); }

                    foreach (int idx in component.SofistikPlateIndexies.Branch(j))
                    { SofistikIndexies.Add(idx, pth1.AppendElement(j)); }
                }

                // CurvePoints
                for (int j = 0; j < component.SofistikCrvPtCoo.BranchCount; j++)
                {
                    GH_Path pth0 = component.SofistikCrvPtCoo.Path(j);

                    foreach (Point3d pt in component.SofistikCrvPtCoo.Branch(j))
                    {
                        //pth1.AppendElement(pth0[0]);
                        //pth1.AppendElement(pth0[1]);
                        //SofistikCrvPtCoo.Add(pt, pth1.AppendElement(pth0[0]));

                        // 2 level Tree
                        SofistikCrvPtCoo.Add(pt, pth1.AppendElement(pth0[0]));

                    }

                    foreach (int idx in component.SofistikCrvPtIdx.Branch(j))
                    {
                        //pth1.AppendElement(pth0[0]);
                        //pth1.AppendElement(pth0[1]);
                        //SofistikCrvPtIdx.Add(idx, pth1.AppendElement(pth0[0]));

                        // 2 level Tree
                        SofistikCrvPtIdx.Add(idx, pth1.AppendElement(pth0[0]));

                    }
                }

                // Curves
                for (int i = 0; i < component.SofistikCurves.BranchCount; i++)
                {
                    GH_Path pth0 = component.SofistikCurves.Path(i);

                    foreach (Curve c in component.SofistikCurves.Branch(i))
                    {
                        SofistikCurves.Add(c, pth1.AppendElement(pth0[0]));
                    }

                }

                // Surfaces
                for (int j = 0; j < component.SofistikSurfaces.BranchCount; j++)
                {

                    foreach (Brep[] p in component.SofistikSurfaces.Branch(j))
                    { SofistikBreps.Add(p[0], pth1.AppendElement(j)); }

                    foreach (int idx in component.SofistikSurfacesIdx.Branch(j))
                    { SofistikBrepsIdx.Add(idx, pth1.AppendElement(j)); }
                }

                componentIdx++;
            }

            //---- End Functions ------------------------------------------------------------------------
            //---- Set Output ---------------------------------------------------------------------------

            DA.SetDataTree(0, SofistikPoints);
            DA.SetDataTree(1, SofistikIndexies);

            DA.SetDataTree(2, SofistikCrvPtCoo);
            DA.SetDataTree(3, SofistikCrvPtIdx);

            DA.SetDataTree(4, SofistikBreps);
            DA.SetDataTree(5, SofistikBrepsIdx);

            DA.SetDataTree(6, SofistikCurves);

            //---- End Set Output -----------------------------------------------------------------------
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //---- Declareing ---------------------------------------------------------------------------

            List <Tri_Loop_Component> All_Components = new List <Tri_Loop_Component>();

            DA.GetDataList <Tri_Loop_Component>("Components", All_Components);

            DataTree <Point3d> SofistikPoints   = new DataTree <Point3d>();
            DataTree <int>     SofistikIndexies = new DataTree <int>();


            DataTree <int>     SofistikCrvPtIdx = new DataTree <int>();
            DataTree <Point3d> SofistikCrvPtCoo = new DataTree <Point3d>();

            DataTree <Brep> SofistikBreps    = new DataTree <Brep>();
            DataTree <int>  SofistikBrepsIdx = new DataTree <int>();

            DataTree <Curve> SofistikCurves = new DataTree <Curve>();

            //---- End Declareing -----------------------------------------------------------------------

            //---- Functions ----------------------------------------------------------------------------

            int componentIdx = 0;

            foreach (Tri_Loop_Component component in All_Components)
            {
                GH_Path pth1 = new GH_Path(componentIdx);

                // run / generate Informations for Sofistik
                component.SofistikInformation();
                component.SofistikCreateSurfaces();

                // Points
                for (int j = 0; j < component.SofistikPlatePoints.BranchCount; j++)
                {
                    foreach (Point3d p in component.SofistikPlatePoints.Branch(j))
                    {
                        SofistikPoints.Add(p, pth1.AppendElement(j));
                    }

                    foreach (int idx in component.SofistikPlateIndexies.Branch(j))
                    {
                        SofistikIndexies.Add(idx, pth1.AppendElement(j));
                    }
                }

                // CurvePoints
                for (int j = 0; j < component.SofistikCrvPtCoo.BranchCount; j++)
                {
                    GH_Path pth0 = component.SofistikCrvPtCoo.Path(j);

                    foreach (Point3d pt in component.SofistikCrvPtCoo.Branch(j))
                    {
                        //pth1.AppendElement(pth0[0]);
                        //pth1.AppendElement(pth0[1]);
                        //SofistikCrvPtCoo.Add(pt, pth1.AppendElement(pth0[0]));

                        // 2 level Tree
                        SofistikCrvPtCoo.Add(pt, pth1.AppendElement(pth0[0]));
                    }

                    foreach (int idx in component.SofistikCrvPtIdx.Branch(j))
                    {
                        //pth1.AppendElement(pth0[0]);
                        //pth1.AppendElement(pth0[1]);
                        //SofistikCrvPtIdx.Add(idx, pth1.AppendElement(pth0[0]));

                        // 2 level Tree
                        SofistikCrvPtIdx.Add(idx, pth1.AppendElement(pth0[0]));
                    }
                }

                // Curves
                for (int i = 0; i < component.SofistikCurves.BranchCount; i++)
                {
                    GH_Path pth0 = component.SofistikCurves.Path(i);

                    foreach (Curve c in component.SofistikCurves.Branch(i))
                    {
                        SofistikCurves.Add(c, pth1.AppendElement(pth0[0]));
                    }
                }

                // Surfaces
                for (int j = 0; j < component.SofistikSurfaces.BranchCount; j++)
                {
                    foreach (Brep[] p in component.SofistikSurfaces.Branch(j))
                    {
                        SofistikBreps.Add(p[0], pth1.AppendElement(j));
                    }

                    foreach (int idx in component.SofistikSurfacesIdx.Branch(j))
                    {
                        SofistikBrepsIdx.Add(idx, pth1.AppendElement(j));
                    }
                }

                componentIdx++;
            }

            //---- End Functions ------------------------------------------------------------------------
            //---- Set Output ---------------------------------------------------------------------------

            DA.SetDataTree(0, SofistikPoints);
            DA.SetDataTree(1, SofistikIndexies);

            DA.SetDataTree(2, SofistikCrvPtCoo);
            DA.SetDataTree(3, SofistikCrvPtIdx);

            DA.SetDataTree(4, SofistikBreps);
            DA.SetDataTree(5, SofistikBrepsIdx);

            DA.SetDataTree(6, SofistikCurves);



            //---- End Set Output -----------------------------------------------------------------------
        }
        // dual loop directly connected to plates
        private void half_dualLoop_type_1(int edgeIndex)
        {
            Edge edge = iSpringMesh.Edges[edgeIndex];

            int rightTriIndex = edge.FirstTriangleIndex;
            int leftTriIndex = edge.SecondTriangleIndex;

            // vertex point
            int vertex1 = edge.FirstVertexIndex;
            int vertex2 = edge.SecondVertexIndex;

            int vertex = vertex1;
            int occupyiedVertex = vertex2;

            if (iVertexStatus[vertex1] == false && iVertexStatus[vertex2] == true) { vertex = vertex1; occupyiedVertex = vertex2; }
            else if (iVertexStatus[vertex2] == false && iVertexStatus[vertex1] == true) { vertex = vertex2; occupyiedVertex = vertex1; }
            else { oInfo += "bug found..."; }

            // layer up
            Point3d rightUp01 = topCenterPts[rightTriIndex];
            Point3d leftUp01 = topCenterPts[leftTriIndex];

            Point3d up03 = topCps[vertex]; //reference point not for construct surfaces

            double planarOffset = planarVerticesValues[vertex];
            double scaler = curveVerticesValues[vertex];
            double openingScalar = openingWidthVerticesValues[vertex];
            double curvePointiness = pointinessValues[vertex];

            //Calculate offset planar points
            Vector3d v_oRightUp01 = up03 - rightUp01;
            Vector3d v_oLeftUp01 = up03 - leftUp01;
            v_oRightUp01.Unitize();
            v_oLeftUp01.Unitize();

            Point3d oRightUp01 = rightUp01 + (v_oRightUp01 * planarOffset);
            Point3d oLeftUp01 = leftUp01 + (v_oLeftUp01 * planarOffset);

            Point3d rightUp02 = (1 - scaler) * oRightUp01 + (scaler) * up03;
            Point3d leftUp02 = (1 - scaler) * oLeftUp01 + (scaler) * up03;

            // normalise hohles
            Point3d openingRightUp02 = up03 + (openingScalar * v_oRightUp01 * -1);
            Point3d openingLeftUp02 = up03 + (openingScalar * v_oLeftUp01 * -1);

            if (new Vector3d(rightUp02 - up03).Length > openingScalar)
                rightUp02 = openingRightUp02;

            if (new Vector3d(leftUp02 - up03).Length > openingScalar)
                leftUp02 = openingLeftUp02;
            // end normalise hohles

            // layer down
            Point3d rightDown01 = bottomCenterPts[rightTriIndex];
            Point3d leftDown01 = bottomCenterPts[leftTriIndex];

            Point3d down03 = bottomCps[vertex]; //reference point not for construct surfaces

            //Calculate offset planar points
            Vector3d v_oRightDownp01 = down03 - rightDown01;
            Vector3d v_oLeftDown01 = down03 - leftDown01;
            v_oRightDownp01.Unitize();
            v_oLeftDown01.Unitize();

            Point3d oRightDown01 = rightDown01 + (v_oRightDownp01 * planarOffset);
            Point3d oLeftDown01 = leftDown01 + (v_oLeftDown01 * planarOffset);

            Point3d rightDown02 = (1 - scaler) * oRightDown01 + (scaler) * down03;
            Point3d leftDown02 = (1 - scaler) * oLeftDown01 + (scaler) * down03;

            // normalise hohles
            Point3d openingRightDown02 = down03 + (openingScalar * v_oRightDownp01 * -1);
            Point3d openingLeftDown02 = down03 + (openingScalar * v_oLeftDown01 * -1);

            if (new Vector3d(rightDown02 - down03).Length > openingScalar)
                rightDown02 = openingRightDown02;

            if (new Vector3d(leftDown02 - down03).Length > openingScalar)
                leftDown02 = openingLeftDown02;
            // end normalise hohles

            //Pointiness
            Point3d maxVertexPt = iSpringMesh.Vertices[vertex].Position;
            Point3d min_rightVertexPt = 0.5 * (rightUp02 + rightDown02);
            Point3d min_leftVertexPt = 0.5 * (leftUp02 + leftDown02);
            Point3d rightVertexPt = (curvePointiness * maxVertexPt) + ((1 - curvePointiness) * min_rightVertexPt);
            Point3d leftVertexPt = (curvePointiness * maxVertexPt) + ((1 - curvePointiness) * min_leftVertexPt);

            // Right Curves (Curved Curve, Planar Part Curve at Top, Planar Part Curve at Bottom, Joined Curve)
            Curve rightLoop = Curve.CreateControlPointCurve(
                new List<Point3d>() { oRightDown01, rightDown02, rightVertexPt, rightUp02, oRightUp01 }, curveDegree);

            Curve rightPlanarUp = Curve.CreateControlPointCurve(
                new List<Point3d>() { oRightUp01, rightUp01 }, 1);

            Curve rightPlanarDown = Curve.CreateControlPointCurve(
                new List<Point3d>() { rightDown01, oRightDown01 }, 1);
            /*
            PolyCurve right = new PolyCurve();
            right.Append(rightPlanarUp);
            right.Append(rightLoop);
            right.Append(rightPlanarDown);*/

            Curve right = Curve.JoinCurves(new List<Curve>() { rightPlanarDown, rightLoop, rightPlanarUp }, documentTolerance, true)[0];

            if (iPolySrf)
            {
                right = rightLoop;
            }

            // Left Curves (Curved Curve, Planar Part Curve at Top, Planar Part Curve at Bottom, Joined Curve)
            Curve leftLoop = Curve.CreateControlPointCurve(
                new List<Point3d>() { oLeftDown01, leftDown02, leftVertexPt, leftUp02, oLeftUp01 }, curveDegree);

            Curve leftPlanarUp = Curve.CreateControlPointCurve(
                new List<Point3d>() { oLeftUp01, leftUp01 }, 1);

            Curve leftPlanarDown = Curve.CreateControlPointCurve(
                new List<Point3d>() { leftDown01, oLeftDown01 }, 1);

            /*
            PolyCurve left = new PolyCurve();
            left.Append(leftPlanarUp);
            left.Append(leftLoop);
            left.Append(leftPlanarDown);*/

            Curve left = Curve.JoinCurves(new List<Curve>() { leftPlanarDown, leftLoop, leftPlanarUp }, documentTolerance, true)[0];

            if (iPolySrf)
            {
                left = leftLoop;
            }

            // compare their polygon index to sort the lofting sequence
            #region compair polygon index

            // dataTree
            int plateID = iPolyLineID[occupyiedVertex];
            plateID = -10 - plateID;     // prevent -1 situation

            GH_Path path = new GH_Path(plateID);

            int[] rightIndex = indexSortPolygon[rightTriIndex];
            int[] leftIndex = indexSortPolygon[leftTriIndex];

            for (int r = 0; r < 3; r++)
                for (int l = 0; l < 3; l++)
                    if (rightIndex[r] == leftIndex[l] && rightIndex[r] != -1 && leftIndex[l] != -1)
                        if ((rightIndex[r + 3] == 0 && leftIndex[l + 3] != 1) ||
                            (leftIndex[l + 3] == 0 && rightIndex[r + 3] != 1) && (rightIndex[r + 3] < leftIndex[l + 3]))
                        {
                            Brep[] brep = Brep.CreateFromLoft(
                                new List<Curve>() { left, right },
                                Point3d.Unset, Point3d.Unset,
                                LoftType.Normal,
                                false
                                );

                            #region allow poly surface
                            if (iPolySrf)
                            {
                                Brep[] brepPlanarUp = Brep.CreateFromLoft(
                                    new List<Curve>() { leftPlanarUp, rightPlanarUp },
                                    Point3d.Unset, Point3d.Unset,
                                    LoftType.Normal, false
                                    );

                                Brep[] brepPlanarDown = Brep.CreateFromLoft(
                                    new List<Curve>() { leftPlanarDown, rightPlanarDown },
                                    Point3d.Unset, Point3d.Unset,
                                    LoftType.Normal, false
                                    );

                                brep = Brep.JoinBreps(new List<Brep>() { brepPlanarDown[0], brep[0], brepPlanarUp[0] }, documentTolerance);
                            }
                            #endregion allow poly surface

                            if (brep.Length > 0)
                            {
                                oDualLoop1.Add(brep[0], path.AppendElement(leftIndex[l + 3]));
                                oDualLoop1ID.Add("H;" + rightTriIndex.ToString() + "-" + leftTriIndex.ToString() + ";" + plateID.ToString(), path.AppendElement(leftIndex[l + 3]));

                                oDualLoop1Curves.Add(left, path.AppendElement(leftIndex[l + 3]));
                                oDualLoop1Curves.Add(right, path.AppendElement(leftIndex[l + 3]));
                            }
                        }
                        else if ((rightIndex[r + 3] == 0 && leftIndex[l + 3] != 1) ||
                                 (leftIndex[l + 3] == 0 && rightIndex[r + 3] != 1) && (rightIndex[r + 3] >= leftIndex[l + 3]))
                        {
                            Brep[] brep = Brep.CreateFromLoft(
                                new List<Curve>() { right, left },
                                Point3d.Unset, Point3d.Unset,
                                LoftType.Normal,
                                false
                                );

                            #region allow poly surface
                            if (iPolySrf)
                            {
                                Brep[] brepPlanarUp = Brep.CreateFromLoft(
                                    new List<Curve>() { rightPlanarUp, leftPlanarUp },
                                    Point3d.Unset, Point3d.Unset,
                                    LoftType.Normal, false
                                    );

                                Brep[] brepPlanarDown = Brep.CreateFromLoft(
                                    new List<Curve>() { rightPlanarDown, leftPlanarDown },
                                    Point3d.Unset, Point3d.Unset,
                                    LoftType.Normal, false
                                    );

                                brep = Brep.JoinBreps(new List<Brep>() { brepPlanarDown[0], brep[0], brepPlanarUp[0] }, documentTolerance);
                            }
                            #endregion allow poly surface

                            if (brep.Length > 0)
                            {
                                oDualLoop1.Add(brep[0], path.AppendElement(rightIndex[r + 3]));
                                oDualLoop1ID.Add("H;" + rightTriIndex.ToString() + "-" + leftTriIndex.ToString() + ";" + plateID.ToString(), path.AppendElement(rightIndex[r + 3]));

                                oDualLoop1Curves.Add(right, path.AppendElement(rightIndex[r + 3]));
                                oDualLoop1Curves.Add(left, path.AppendElement(rightIndex[r + 3]));
                            }
                        }
                        else if (rightIndex[r + 3] >= leftIndex[l + 3])
                        {
                            Brep[] brep = Brep.CreateFromLoft(
                                new List<Curve>() { left, right },
                                Point3d.Unset, Point3d.Unset,
                                LoftType.Normal,
                                false
                                );

                            #region allow poly surface
                            if (iPolySrf)
                            {
                                Brep[] brepPlanarUp = Brep.CreateFromLoft(
                                    new List<Curve>() { leftPlanarUp, rightPlanarUp },
                                    Point3d.Unset, Point3d.Unset,
                                    LoftType.Normal, false
                                    );

                                Brep[] brepPlanarDown = Brep.CreateFromLoft(
                                    new List<Curve>() { leftPlanarDown, rightPlanarDown },
                                    Point3d.Unset, Point3d.Unset,
                                    LoftType.Normal, false
                                    );

                                brep = Brep.JoinBreps(new List<Brep>() { brepPlanarDown[0], brep[0], brepPlanarUp[0] }, documentTolerance);
                            }
                            #endregion allow poly surface

                            if (brep.Length > 0)
                            {
                                oDualLoop1.Add(brep[0], path.AppendElement(leftIndex[l + 3]));
                                oDualLoop1ID.Add("H;" + rightTriIndex.ToString() + "-" + leftTriIndex.ToString() + ";" + plateID.ToString(), path.AppendElement(leftIndex[l + 3]));

                                oDualLoop1Curves.Add(left, path.AppendElement(leftIndex[l + 3]));
                                oDualLoop1Curves.Add(right, path.AppendElement(leftIndex[l + 3]));
                            }
                        }
                        else if (rightIndex[r + 3] < leftIndex[l + 3])
                        {
                            Brep[] brep = Brep.CreateFromLoft(
                                new List<Curve>() { right, left },
                                Point3d.Unset, Point3d.Unset,
                                LoftType.Normal,
                                false
                                );

                            #region allow poly surface
                            if (iPolySrf)
                            {
                                Brep[] brepPlanarUp = Brep.CreateFromLoft(
                                    new List<Curve>() { rightPlanarUp, leftPlanarUp },
                                    Point3d.Unset, Point3d.Unset,
                                    LoftType.Normal, false
                                    );

                                Brep[] brepPlanarDown = Brep.CreateFromLoft(
                                    new List<Curve>() { rightPlanarDown, leftPlanarDown },
                                    Point3d.Unset, Point3d.Unset,
                                    LoftType.Normal, false
                                    );

                                brep = Brep.JoinBreps(new List<Brep>() { brepPlanarDown[0], brep[0], brepPlanarUp[0] }, documentTolerance);
                            }
                            #endregion allow poly surface

                            if (brep.Length > 0)
                            {
                                oDualLoop1.Add(brep[0], path.AppendElement(rightIndex[r + 3]));
                                oDualLoop1ID.Add("H;" + rightTriIndex.ToString() + "-" + leftTriIndex.ToString() + ";" + plateID.ToString(), path.AppendElement(rightIndex[r + 3]));

                                oDualLoop1Curves.Add(right, path.AppendElement(rightIndex[r + 3]));
                                oDualLoop1Curves.Add(left, path.AppendElement(rightIndex[r + 3]));
                            }
                        }
            #endregion compair polygon index
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //---- Declareing ---------------------------------------------------------------------------
            GH_Structure <GH_Brep> AllStripes;

            DA.GetDataTree("Triloop Stipes", out AllStripes);

            GH_Structure <GH_Point> AllPoints;

            DA.GetDataTree("Points", out AllPoints);

            bool Reorient = false;

            DA.GetData <bool>("Merge Stripes", ref Reorient);

            bool Switch = false;

            DA.GetData <bool>("Switch", ref Switch);

            int Seam = 0;

            DA.GetData <int>("Seam", ref Seam);



            DataTree <Brep>    AllUnrolledBreps  = new DataTree <Brep>();
            DataTree <Brep>    ForReorientBreps  = new DataTree <Brep>();
            DataTree <Plane>   AllOrientPlanes   = new DataTree <Plane>();
            DataTree <Curve>   AllSharedCurves   = new DataTree <Curve>();
            DataTree <Point3d> AllUnrolledPoints = new DataTree <Point3d>();

            //---- End Declareing -----------------------------------------------------------------------
            //---- Functions ----------------------------------------------------------------------------

            #region Unroll

            for (int i = 0; i < AllStripes.Branches.Count; i++)
            {
                GH_Path pth           = new GH_Path(i);
                GH_Path originalPath  = AllStripes.Paths[i];
                int     stripecounter = 0;

                foreach (GH_Brep gbrep in AllStripes[i])
                {
                    Unroller unroll = new Unroller(gbrep.Value);
                    // Add points to unroll with
                    if (AllPoints.Branches.Count != 0)
                    {
                        foreach (GH_Point pt in AllPoints[i])
                        {
                            unroll.AddFollowingGeometry(pt.Value);
                        }
                    }


                    unroll.ExplodeOutput = false;

                    Curve[]   curves;
                    Point3d[] unrolledPoints;
                    TextDot[] dots;
                    Brep[]    unrolledBreps = unroll.PerformUnroll(out curves, out unrolledPoints, out dots);

                    if (Reorient == false)
                    {
                        foreach (Brep b in unrolledBreps)
                        {
                            AllUnrolledBreps.Add(b, originalPath);
                        }

                        foreach (Point3d p in unrolledPoints)
                        {
                            AllUnrolledPoints.Add(p, originalPath);
                        }
                    }

                    else
                    {
                        foreach (Brep b in unrolledBreps)
                        {
                            AllUnrolledBreps.Add(b, pth.AppendElement(stripecounter));
                        }
                    }

                    // For reorientation
                    if (Reorient == true)
                    {
                        ForReorientBreps.Add(unrolledBreps[Seam], pth);
                    }

                    stripecounter++;
                }
            }
            #endregion unroll

            if (Reorient == true)
            {
                //ForReorientBreps.Branch(0)[0].Curves3D[0].PointAtEnd;

                for (int i = 0; i < ForReorientBreps.BranchCount; i++)
                {
                    GH_Path pth = new GH_Path(i);

                    foreach (Curve crv0 in ForReorientBreps.Branch(i)[0].Curves3D)
                    {
                        foreach (Curve crv1 in ForReorientBreps.Branch(i)[1].Curves3D)
                        {
                            double l0 = crv0.GetLength();
                            double l1 = crv1.GetLength();

                            if (Math.Abs(l0 - l1) < 0.00001)
                            {
                                // orient crv0
                                Plane origin0 = new Plane(new Point3d(0, 0, 0), new Vector3d(1, 0, 0), new Vector3d(0, 1, 0));
                                Plane target0 = new Plane(origin0);
                                AllOrientPlanes.Add(origin0, pth.AppendElement(0));
                                AllOrientPlanes.Add(target0, pth.AppendElement(0));


                                // orient crv1
                                Vector3d vect0   = crv1.TangentAtStart;
                                Vector3d vect1   = Vector3d.CrossProduct(vect0, new Vector3d(0.0, 0.0, 1.0));
                                Plane    origin1 = new Plane(crv1.PointAtStart, vect0, vect1);

                                Vector3d vect2   = new Vector3d();
                                Vector3d vect3   = new Vector3d();
                                Plane    target1 = new Plane();

                                if (Switch == true)
                                {
                                    vect2   = crv0.TangentAtStart;
                                    vect3   = Vector3d.CrossProduct(vect2, new Vector3d(0.0, 0.0, 1.0));
                                    target1 = new Plane(crv0.PointAtStart, vect2, vect3);
                                }

                                else
                                {
                                    vect2   = crv0.TangentAtStart;
                                    vect3   = Vector3d.CrossProduct(-vect2, new Vector3d(0.0, 0.0, 1.0));
                                    target1 = new Plane(crv0.PointAtEnd, -vect2, vect3);
                                }


                                AllOrientPlanes.Add(origin1, pth.AppendElement(1));
                                AllOrientPlanes.Add(target1, pth.AppendElement(1));
                                // shared curve of stripe0 and stripe 1
                                AllSharedCurves.Add(crv0, pth.AppendElement(0));
                                AllSharedCurves.Add(crv1, pth.AppendElement(0));
                            }
                        }

                        // orient crv2
                        foreach (Curve crv2 in ForReorientBreps.Branch(i)[2].Curves3D)
                        {
                            double l0 = crv0.GetLength();
                            double l1 = crv2.GetLength();

                            if (Math.Abs(l0 - l1) < 0.00001)
                            {
                                Vector3d vect0   = crv2.TangentAtStart;
                                Vector3d vect1   = Vector3d.CrossProduct(vect0, new Vector3d(0.0, 0.0, 1.0));
                                Plane    origin2 = new Plane(crv2.PointAtStart, vect0, vect1);

                                Vector3d vect2   = new Vector3d();
                                Vector3d vect3   = new Vector3d();
                                Plane    target2 = new Plane();

                                if (Switch == true)
                                {
                                    vect2   = crv0.TangentAtStart;
                                    vect3   = Vector3d.CrossProduct(vect2, new Vector3d(0.0, 0.0, 1.0));
                                    target2 = new Plane(crv0.PointAtStart, vect2, vect3);
                                }

                                else
                                {
                                    vect2   = crv0.TangentAtStart;
                                    vect3   = Vector3d.CrossProduct(-vect2, new Vector3d(0.0, 0.0, 1.0));
                                    target2 = new Plane(crv0.PointAtEnd, -vect2, vect3);
                                }

                                AllOrientPlanes.Add(origin2, pth.AppendElement(2));
                                AllOrientPlanes.Add(target2, pth.AppendElement(2));
                                // shared curve of stripe0 and stripe 2
                                AllSharedCurves.Add(crv2, pth.AppendElement(2));
                                AllSharedCurves.Add(crv0, pth.AppendElement(2));
                            }
                        }
                    }
                    // find the shared curve oft stripe 1 and stripe 2
                    foreach (Curve crv1 in ForReorientBreps.Branch(i)[1].Curves3D)
                    {
                        foreach (Curve crv2 in ForReorientBreps.Branch(i)[2].Curves3D)
                        {
                            double l1 = crv1.GetLength();
                            double l2 = crv2.GetLength();

                            // shared curve of stripe1 and stripe 2
                            if (Math.Abs(l1 - l2) < 0.00001)
                            {
                                AllSharedCurves.Add(crv1, pth.AppendElement(1));
                                AllSharedCurves.Add(crv2, pth.AppendElement(1));
                            }
                        }
                    }
                }
            }



            //---- End Functions --------------------------------------------------------------------------
            //----Set Output-------------------------------------------------------------------------------

            DA.SetDataTree(0, AllUnrolledBreps);
            DA.SetDataTree(1, AllOrientPlanes);
            DA.SetDataTree(2, AllSharedCurves);
            DA.SetDataTree(3, AllUnrolledPoints);

            //----End Set Output---------------------------------------------------------------------------
        }
Example #17
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <GH_Glulam> inputs = new List <GH_Glulam>();

            Glulam glulam = null;

            //DataTree<GH_Glulam> glulams = new DataTree<GH_Glulam>();
            GH_Structure <IGH_Goo> glulams;

            if (!DA.GetDataTree <IGH_Goo>(GlulamInput, out glulams))
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "No glulam blank connected.");
                return;
            }

            int type = 0;

            DA.GetData("Type", ref type);

            DataTree <object> output  = new DataTree <object>();
            DataTree <string> species = new DataTree <string>();
            DataTree <Guid>   ids     = new DataTree <Guid>();

            GH_Path element_path;

            foreach (var path in glulams.Paths)
            {
                var branch = glulams[path];
                for (int i = 0; i < branch.Count; ++i)
                {
                    IGH_Goo goo       = branch[i];
                    var     gh_glulam = goo as GH_Glulam;
                    if (gh_glulam == null)
                    {
                        continue;
                    }

                    glulam = gh_glulam.Value;
                    if (glulam == null)
                    {
                        continue;
                    }

                    GH_Path new_path = new GH_Path(path);
                    path.AppendElement(i);

                    int j = 0;

                    var objects = new List <object>();
                    switch (type)
                    {
                    case (1):
                        objects.AddRange(glulam.GetLamellaeMeshes());
                        break;

                    case (2):
                        objects.AddRange(glulam.GetLamellaeBreps());
                        break;

                    default:
                        objects.AddRange(glulam.GetLamellaeCurves());
                        break;
                    }

                    if (objects.Count < 1)
                    {
                        throw new NotImplementedException();
                    }

                    for (int x = 0; x < glulam.Data.NumWidth; ++x)
                    {
                        for (int y = 0; y < glulam.Data.NumHeight; ++y)
                        {
                            //new_path = new GH_Path(x, y);
                            element_path = new GH_Path(new_path);
                            element_path.AppendElement(x);
                            element_path.AppendElement(y);

                            output.Add(objects[j], element_path);
                            if (glulam.Data.Lamellae[x, y] != null)
                            {
                                species.Add(glulam.Data.Lamellae[x, y].Species, element_path);
                                ids.Add(glulam.Data.Lamellae[x, y].Reference, element_path);
                            }
                            j++;
                        }
                    }
                }
            }

            //for (int i = 0; i < inputs.Count; ++i)
            //{

            //    Glulam g = inputs[i].Value;


            DA.SetDataTree(0, output);
            DA.SetDataTree(1, species);
            DA.SetDataTree(2, ids);
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //---- Declareing ---------------------------------------------------------------------------

            List <Tri_Loop_Component> All_Components = new List <Tri_Loop_Component>();

            DA.GetDataList <Tri_Loop_Component>("Components", All_Components);


            DataTree <Curve> All_Curves = new DataTree <Curve>();

            //// =======================================================================================
            // Added by Gene
            DataTree <Curve> All_ExtendedCurves    = new DataTree <Curve>();
            DataTree <Brep>  All_SingleStripeBreps = new DataTree <Brep>();

            //// =======================================================================================

            DataTree <Point3d> All_CentrePointsL01 = new DataTree <Point3d>();
            DataTree <Point3d> All_CentrePointsL02 = new DataTree <Point3d>();
            DataTree <Curve>   All_PlateCrv        = new DataTree <Curve>();

            DataTree <Point3d> All_PentagonPts_L01 = new DataTree <Point3d>();
            DataTree <Point3d> All_PentagonPts_L02 = new DataTree <Point3d>();

            DataTree <int>   All_StripeIds            = new DataTree <int>();
            DataTree <Brep>  All_StripeBreps          = new DataTree <Brep>();
            DataTree <Curve> All_StripeIntersectCrvs  = new DataTree <Curve>();
            DataTree <Plane> All_StripeIntersectPlane = new DataTree <Plane>();

            //---- End Declareing -----------------------------------------------------------------------
            //---- Functions ----------------------------------------------------------------------------

            int componentIdx = 0;

            foreach (Tri_Loop_Component component in All_Components)
            {
                GH_Path pth1 = new GH_Path(componentIdx);

                // run / generate Informations for Sofistik
                // create output information
                for (int p = 0; p < component.CentersL01.Count; p++)
                {
                    All_CentrePointsL01.Add(component.CentersL01[p], pth1);
                    All_CentrePointsL02.Add(component.CentersL02[p], pth1);
                }

                for (int c = 0; c < component.Curves.BranchCount; c++)
                {
                    All_Curves.Add(component.Curves.Branch(c)[0], pth1.AppendElement(c));
                    All_Curves.Add(component.Curves.Branch(c)[1], pth1.AppendElement(c));

                    //// =======================================================================================
                    // Added by Gene
                    All_ExtendedCurves.Add(component.ExtendedCurves.Branch(c)[0], pth1.AppendElement(c));
                    All_ExtendedCurves.Add(component.ExtendedCurves.Branch(c)[1], pth1.AppendElement(c));
                    //// =======================================================================================
                }

                for (int sid = 0; sid < component.StripeID.BranchCount; sid++)
                {
                    All_StripeIds.Add(component.StripeID.Branch(sid)[0], pth1.AppendElement(sid));
                    All_StripeIds.Add(component.StripeID.Branch(sid)[1], pth1.AppendElement(sid));
                    All_StripeIds.Add(component.StripeID.Branch(sid)[2], pth1.AppendElement(sid));
                }

                for (int p = 0; p < component.PlateCrv.BranchCount; p++)
                {
                    All_PlateCrv.Add(component.PlateCrv.Branch(p)[0], pth1.AppendElement(p));
                    All_PlateCrv.Add(component.PlateCrv.Branch(p)[1], pth1.AppendElement(p));
                }

                for (int pent = 0; pent < component.PlanarPentagonL01.BranchCount; pent++)
                {
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[0], pth1.AppendElement(pent));
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[1], pth1.AppendElement(pent));
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[2], pth1.AppendElement(pent));
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[3], pth1.AppendElement(pent));
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[4], pth1.AppendElement(pent));
                }

                for (int pent = 0; pent < component.PlanarPentagonL02.BranchCount; pent++)
                {
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[0], pth1.AppendElement(pent));
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[1], pth1.AppendElement(pent));
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[2], pth1.AppendElement(pent));
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[3], pth1.AppendElement(pent));
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[4], pth1.AppendElement(pent));
                }

                // Information from Stripe Class
                for (int s = 0; s < component.Stripes.Count; s++)
                {
                    for (int t = 0; t < component.Stripes[s].SurfaceAtLoop.Length; t++)
                    {
                        All_StripeBreps.Add(component.Stripes[s].SurfaceAtLoop[t], pth1.AppendElement(s));
                    }

                    //for (int u = 0; u < component.Stripes[s].IntersectionCurve.Length; u++)
                    //{ All_StripeIntersectCrvs.Add(component.Stripes[s].IntersectionCurve[u], pth1.AppendElement(s));}

                    All_StripeIntersectPlane.Add(component.Stripes[s].IntersectionPlane, pth1.AppendElement(s));
                }

                // ======================================================================================================
                // Gene Added

                for (int s = 0; s < component.StripesSingle.Count; s++)
                {
                    All_SingleStripeBreps.Add(component.StripesSingle[s].loop, pth1.AppendElement(s));

                    //for (int u = 0; u < component.Stripes[s].IntersectionCurve.Length; u++)
                    //{ All_StripeIntersectCrvs.Add(component.Stripes[s].IntersectionCurve[u], pth1.AppendElement(s));}

                    //All_StripeIntersectPlane.Add(component.StripesSingle[s].IntersectionPlane, pth1.AppendElement(s));
                }

                // ======================================================================================================

                componentIdx++;
            }

            //---- End Functions ------------------------------------------------------------------------
            //---- Set Output ---------------------------------------------------------------------------

            DA.SetDataTree(0, All_CentrePointsL01);
            DA.SetDataTree(1, All_CentrePointsL02);
            DA.SetDataTree(2, All_Curves);
            DA.SetDataTree(3, All_PlateCrv);
            DA.SetDataTree(4, All_PentagonPts_L01);
            DA.SetDataTree(5, All_PentagonPts_L02);
            DA.SetDataTree(6, All_StripeIds);
            DA.SetDataTree(7, All_StripeBreps);
            DA.SetDataTree(8, All_StripeIntersectPlane);

            //// =======================================================================================
            // Added by Gene

            DA.SetDataTree(9, All_ExtendedCurves);
            DA.SetDataTree(10, All_SingleStripeBreps);
            //// =======================================================================================

            //---- End Set Output -----------------------------------------------------------------------
        }
        public void SofistikInformation_Version2()
        {
            GH_Path pthPlanarL01 = new GH_Path(0);
            GH_Path pthPlanarL02 = new GH_Path(1);
            GH_Path pthLoop00 = new GH_Path(2);
            GH_Path pthLoop01 = new GH_Path(3);
            GH_Path pthLoop02 = new GH_Path(4);

            #region Sofistik Points

            for (int i = 0; i < 3; i++)
            {
                //planar Part Points L01
                AllSofistikPoints.Add(RightfromCenterL01[i], pthPlanarL01);
                SofistikIndexies.Add(i + 0 + (i * 2), pthPlanarL01);

                AllSofistikPoints.Add(CentersL01[i], pthPlanarL01);
                SofistikIndexies.Add(i + 1 + (i * 2), pthPlanarL01);

                AllSofistikPoints.Add(LeftfromCenterL01[i], pthPlanarL01);
                SofistikIndexies.Add(i + 2 + (i * 2), pthPlanarL01);

                //planar Part Points L02
                AllSofistikPoints.Add(RightfromCenterL02[i], pthPlanarL02);
                SofistikIndexies.Add(i + 10 + (i * 2), pthPlanarL02);

                AllSofistikPoints.Add(CentersL02[i], pthPlanarL02);
                SofistikIndexies.Add(i + 11 + (i * 2), pthPlanarL02);

                AllSofistikPoints.Add(LeftfromCenterL02[i], pthPlanarL02);
                SofistikIndexies.Add(i + 12 + (i * 2), pthPlanarL02);

                #region Sofistik Plate

                //---- Sofistik Plate Curves ---------------------------------------------------------------------------
                //planar Part Points L01
                SofistikPlatePoints.Add(RightfromCenterL01[i], pthPlanarL01);
                SofistikPlateIndexies.Add(i + 0 + (i * 2), pthPlanarL01);

                SofistikPlatePoints.Add(CentersL01[i], pthPlanarL01);
                SofistikPlateIndexies.Add(i + 1 + (i * 2), pthPlanarL01);

                SofistikPlatePoints.Add(LeftfromCenterL01[i], pthPlanarL01);
                SofistikPlateIndexies.Add(i + 2 + (i * 2), pthPlanarL01);

                //planar Part Points L02
                SofistikPlatePoints.Add(RightfromCenterL02[i], pthPlanarL02);
                SofistikPlateIndexies.Add(i + 10 + (i * 2), pthPlanarL02);

                SofistikPlatePoints.Add(CentersL02[i], pthPlanarL02);
                SofistikPlateIndexies.Add(i + 11 + (i * 2), pthPlanarL02);

                SofistikPlatePoints.Add(LeftfromCenterL02[i], pthPlanarL02);
                SofistikPlateIndexies.Add(i + 12 + (i * 2), pthPlanarL02);
                #endregion Sofistik Plate

            }

            for (int i = 0; i < 3; i++)
            {
                int counter = 0;
                foreach (Curve c in Curves.Branch(i))
                {
                    AllSofistikPoints.Add(c.PointAtNormalizedLength(0.0), new GH_Path(i + 2));

                    // check for corresponding point index
                    for (int k = 0; k < AllSofistikPoints.Branch(0).Count; k++)
                    {
                        if ((Math.Abs(c.PointAtNormalizedLength(0.0).X - AllSofistikPoints.Branch(0)[k].X) < 0.001) &&
                           (Math.Abs(c.PointAtNormalizedLength(0.0).Y - AllSofistikPoints.Branch(0)[k].Y) < 0.001))
                        { SofistikIndexies.Add(SofistikIndexies.Branch(0)[k], new GH_Path(i + 2)); }
                    }

                    //AllSofistikPoints.Add(c.PointAtNormalizedLength(0.5), new GH_Path(i + 2));

                    // check for corresponding point index
                    //SofistikIndexies.Add(i * 2 + counter + 20, new GH_Path(i + 2));

                    AllSofistikPoints.Add(c.PointAtNormalizedLength(1.0), new GH_Path(i + 2));

                    // check for corresponding point index
                    for (int k = 0; k < AllSofistikPoints.Branch(1).Count; k++)
                    {
                        if ((Math.Abs(c.PointAtNormalizedLength(1.0).X - AllSofistikPoints.Branch(1)[k].X) < 0.001) &&
                            (Math.Abs(c.PointAtNormalizedLength(1.0).Y - AllSofistikPoints.Branch(1)[k].Y) < 0.001))
                        { SofistikIndexies.Add(SofistikIndexies.Branch(1)[k], new GH_Path(i + 2)); }
                    }

                    counter++;
                }
            }
            #endregion Sofistik Points

            #region Sofistik Curves

            // planar Curves

            //L01
            #region L01
            for (int i = 0; i < AllSofistikPoints.Branch(0).Count; i++)
            {
                if (i < AllSofistikPoints.Branch(0).Count - 1)
                {
                    GH_Path p = new GH_Path(0);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(0)[i], p);
                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(0)[i + 1], p);

                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(0)[i], p);
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(0)[i + 1], p);
                }
                else
                {
                    GH_Path p = new GH_Path(0);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(0)[i], p);
                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(0)[0], p);

                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(0)[i], p);
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(0)[0], p);

                }
            }
            #endregion L01

            //L02
            #region L02
            for (int i = 0; i < AllSofistikPoints.Branch(1).Count; i++)
            {
                if (i < AllSofistikPoints.Branch(1).Count - 1)
                {
                    GH_Path p = new GH_Path(1);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(1)[i], p);
                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(1)[i + 1], p);

                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(1)[i], p);
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(1)[i + 1], p);

                }
                else
                {
                    GH_Path p = new GH_Path(1);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(1)[i], p);
                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(1)[0], p);

                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(1)[i], p);
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(1)[0], p);

                }
            }
            #endregion L02

            //Curves A
            #region Crv A
            for (int i = 0; i < AllSofistikPoints.Branch(2).Count; i++)
            {
                if (i < AllSofistikPoints.Branch(2).Count * 0.5)
                {
                    // Left Curve
                    GH_Path p = new GH_Path(2);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(2)[i], p);
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(2)[i], p);

                }
                else
                {
                    // Right Curve
                    GH_Path p = new GH_Path(2);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(2)[i], p);
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(2)[i], p);
                }
            }
            #endregion Crv A

            //Curves B
            #region Crv B
            for (int i = 0; i < AllSofistikPoints.Branch(3).Count; i++)
            {
                if (i < AllSofistikPoints.Branch(3).Count * 0.5)
                {
                    // Left Curve
                    GH_Path p = new GH_Path(3);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(3)[i], p);
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(3)[i], p);
                }
                else
                {
                    // Right Curve
                    GH_Path p = new GH_Path(3);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(3)[i], p);
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(3)[i], p);
                }
            }
            #endregion Crv B

            //Curves C
            #region Crv C
            for (int i = 0; i < AllSofistikPoints.Branch(4).Count; i++)
            {
                if (i < AllSofistikPoints.Branch(4).Count * 0.5)
                {
                    // Left Curve
                    GH_Path p = new GH_Path(4);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(4)[i], new GH_Path(p));
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(4)[i], new GH_Path(p));
                }
                else
                {
                    // Right Curve
                    GH_Path p = new GH_Path(4);
                    p.AppendElement(i);

                    SofistikCrvPtIdx.Add(SofistikIndexies.Branch(4)[i], new GH_Path(p));
                    SofistikCrvPtCoo.Add(AllSofistikPoints.Branch(4)[i], new GH_Path(p));
                }
            }
            #endregion Crv C

            //Curves AL-BR
            #region  AL-BR
            // adds te planar curves at the top and bottum of the bended curves in order to close the boundary curves of th surface
            GH_Path albr = new GH_Path(2);
            // i takes the start points and the endpoints of the bended curves and puts them in a branch
            //L01
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(albr.AppendElement(0))[0], albr.AppendElement(2)); // start point of first bended curve in path {2;0} element idx [0]
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(albr.AppendElement(1))[0], albr.AppendElement(2)); // start point of second bended curve in path {2;1} element idx [0]
            // stores it in path {2;2}
            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(albr.AppendElement(0))[0], albr.AppendElement(2));
            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(albr.AppendElement(1))[0], albr.AppendElement(2));
            //L02
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(albr.AppendElement(0))[1], albr.AppendElement(3));
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(albr.AppendElement(1))[1], albr.AppendElement(3));

            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(albr.AppendElement(0))[1], albr.AppendElement(3));
            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(albr.AppendElement(1))[1], albr.AppendElement(3));
            #endregion  AL-BR

            //Curves BL-CR
            #region  BL-CR

            GH_Path blcr = new GH_Path(3);
            //L01
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(blcr.AppendElement(0))[0], blcr.AppendElement(2));
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(blcr.AppendElement(1))[0], blcr.AppendElement(2));

            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(blcr.AppendElement(0))[0], blcr.AppendElement(2));
            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(blcr.AppendElement(1))[0], blcr.AppendElement(2));
            //L02
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(blcr.AppendElement(0))[1], blcr.AppendElement(3));
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(blcr.AppendElement(1))[1], blcr.AppendElement(3));

            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(blcr.AppendElement(0))[1], blcr.AppendElement(3));
            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(blcr.AppendElement(1))[1], blcr.AppendElement(3));
            #endregion  BL-CR

            //Curves CL-AR
            #region  CL-AR

            GH_Path clar = new GH_Path(4);
            //L01
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(clar.AppendElement(0))[0], clar.AppendElement(2));
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(clar.AppendElement(1))[0], clar.AppendElement(2));

            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(clar.AppendElement(0))[0], clar.AppendElement(2));
            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(clar.AppendElement(1))[0], clar.AppendElement(2));
            //L02
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(clar.AppendElement(0))[1], clar.AppendElement(3));
            SofistikCrvPtCoo.Add(SofistikCrvPtCoo.Branch(clar.AppendElement(1))[1], clar.AppendElement(3));

            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(clar.AppendElement(0))[1], clar.AppendElement(3));
            SofistikCrvPtIdx.Add(SofistikCrvPtIdx.Branch(clar.AppendElement(1))[1], clar.AppendElement(3));
            #endregion  CL-AR

            #endregion Sofistik Curves
        }
        /// <summary>
        /// Population cluster data for the component output. Outputs normalised genes values.
        /// </summary>
        /// <param name="pop">Uses the given population to set the cluster output data</param>
        public void SetComponentOut(Population pop, List <BioBranch> BioBranches)
        {
            // Curent pop
            populationNumbers = new GH_Structure <GH_Number>();

            for (int i = 0; i < pop.chromosomes.Length; i++)
            {
                GH_Path myPath = new GH_Path(i);

                List <GH_Number> myList = new List <GH_Number>();
                for (int k = 0; k < pop.chromosomes[i].GetGenes().Length; k++)
                {
                    GH_Number myGHNumber = new GH_Number(pop.chromosomes[i].GetGenes()[k]);
                    myList.Add(myGHNumber);
                }

                populationNumbers.AppendRange(myList, myPath);
            }


            // Cluster data
            clusterNumbers = new GH_Structure <GH_Number>();

            for (int i = 0; i < 12; i++)
            {
                GH_Path myPath       = new GH_Path(i);
                int     localCounter = 0;

                // Go through all the chromosomes. If cluster ID of it equals 'i', then stick it in the branch.
                for (int j = 0; j < pop.chromosomes.Length; j++)
                {
                    List <GH_Number> myList = new List <GH_Number>();

                    if (pop.chromosomes[j].clusterId == i)
                    {
                        for (int k = 0; k < pop.chromosomes[j].GetGenes().Length; k++)
                        {
                            GH_Number myGHNumber = new GH_Number(pop.chromosomes[j].GetGenes()[k]);
                            myList.Add(myGHNumber);
                        }

                        clusterNumbers.AppendRange(myList, myPath.AppendElement(localCounter));
                        localCounter++;
                    }
                }
            }


            // Historic pop
            historicNumbers = new GH_Structure <GH_Number>();

            for (int i = 0; i < BioBranches.Count; i++)
            {
                for (int j = 0; j < BioBranches[i].Twigs.Count; j++)
                {
                    for (int k = 0; k < BioBranches[i].Twigs[j].chromosomes.Length; k++)
                    {
                        List <GH_Number> myList = new List <GH_Number>();
                        for (int c = 0; c < pop.chromosomes[k].GetGenes().Length; c++)
                        {
                            GH_Number myGHNumber = new GH_Number(BioBranches[i].Twigs[j].chromosomes[k].GetGenes()[c]);
                            myList.Add(myGHNumber);
                        }

                        GH_Path myPath = new GH_Path(i, j, k);
                        historicNumbers.AppendRange(myList, myPath);
                    }
                }
            }



            this.ExpireSolution(true);
        }
        private void triLoop()
        {
            for (int tri = 0; tri < iSpringMesh.Triangles.Count; tri++)
            {
                GH_Path path = new GH_Path(tri);
                //oInfo += "path = " + path.ToString() + "\n";
                Triangle triangle = iSpringMesh.Triangles[tri];

                if (!iVertexStatus[triangle.FirstVertexIndex] &&
                    !iVertexStatus[triangle.SecondVertexIndex] &&
                    !iVertexStatus[triangle.ThirdVertexIndex])
                {
                    // ids
                    oTriLoopID.Add("T;" + tri.ToString() + ";" + triangle.SecondAdjTriIndex.ToString() + ";" + triangle.ThirdAdjTriIndex.ToString(), path.AppendElement(0));
                    oTriLoopID.Add("T;" + tri.ToString() + ";" + triangle.ThirdAdjTriIndex.ToString() + ";" + triangle.FirstAdjTriIndex.ToString(), path.AppendElement(1));
                    oTriLoopID.Add("T;" + tri.ToString() + ";" + triangle.FirstAdjTriIndex.ToString() + ";" + triangle.SecondAdjTriIndex.ToString(), path.AppendElement(2));

                    // stripes
                    createStripe(triangle.FirstVertexIndex, triangle.SecondVertexIndex, triangle.ThirdVertexIndex, path, 0);
                    createStripe(triangle.SecondVertexIndex, triangle.ThirdVertexIndex, triangle.FirstVertexIndex, path, 1);
                    createStripe(triangle.ThirdVertexIndex, triangle.FirstVertexIndex, triangle.SecondVertexIndex, path, 2);
                }
            }
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //---- Declareing ---------------------------------------------------------------------------

            List<Tri_Loop_Component> All_Components = new List<Tri_Loop_Component>();
            DA.GetDataList<Tri_Loop_Component>("Components", All_Components);

            DataTree<Curve> All_Curves = new DataTree<Curve>();

            //// =======================================================================================
            // Added by Gene
            DataTree<Curve> All_ExtendedCurves = new DataTree<Curve>();
            DataTree<Brep> All_SingleStripeBreps = new DataTree<Brep>();

            //// =======================================================================================

            DataTree<Point3d> All_CentrePointsL01 = new DataTree<Point3d>();
            DataTree<Point3d> All_CentrePointsL02 = new DataTree<Point3d>();
            DataTree<Curve> All_PlateCrv = new DataTree<Curve>();

            DataTree<Point3d> All_PentagonPts_L01 = new DataTree<Point3d>();
            DataTree<Point3d> All_PentagonPts_L02 = new DataTree<Point3d>();

            DataTree<int> All_StripeIds = new DataTree<int>();
            DataTree<Brep> All_StripeBreps = new DataTree<Brep>();
            DataTree<Curve> All_StripeIntersectCrvs = new DataTree<Curve>();
            DataTree<Plane> All_StripeIntersectPlane = new DataTree<Plane>();

            //---- End Declareing -----------------------------------------------------------------------
            //---- Functions ----------------------------------------------------------------------------

            int componentIdx = 0;

            foreach (Tri_Loop_Component component in All_Components)
            {
                GH_Path pth1 = new GH_Path(componentIdx);

                // run / generate Informations for Sofistik
                // create output information
                for (int p = 0; p < component.CentersL01.Count; p++)
                {
                    All_CentrePointsL01.Add(component.CentersL01[p], pth1);
                    All_CentrePointsL02.Add(component.CentersL02[p], pth1);
                }

                for (int c = 0; c < component.Curves.BranchCount; c++)
                {
                    All_Curves.Add(component.Curves.Branch(c)[0], pth1.AppendElement(c));
                    All_Curves.Add(component.Curves.Branch(c)[1], pth1.AppendElement(c));

                    //// =======================================================================================
                    // Added by Gene
                    All_ExtendedCurves.Add(component.ExtendedCurves.Branch(c)[0], pth1.AppendElement(c));
                    All_ExtendedCurves.Add(component.ExtendedCurves.Branch(c)[1], pth1.AppendElement(c));
                    //// =======================================================================================
                }

                for (int sid = 0; sid < component.StripeID.BranchCount; sid++)
                {
                    All_StripeIds.Add(component.StripeID.Branch(sid)[0], pth1.AppendElement(sid));
                    All_StripeIds.Add(component.StripeID.Branch(sid)[1], pth1.AppendElement(sid));
                    All_StripeIds.Add(component.StripeID.Branch(sid)[2], pth1.AppendElement(sid));
                }

                for (int p = 0; p < component.PlateCrv.BranchCount; p++)
                {
                    All_PlateCrv.Add(component.PlateCrv.Branch(p)[0], pth1.AppendElement(p));
                    All_PlateCrv.Add(component.PlateCrv.Branch(p)[1], pth1.AppendElement(p));
                }

                for (int pent = 0; pent < component.PlanarPentagonL01.BranchCount; pent++)
                {
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[0], pth1.AppendElement(pent));
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[1], pth1.AppendElement(pent));
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[2], pth1.AppendElement(pent));
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[3], pth1.AppendElement(pent));
                    All_PentagonPts_L01.Add(component.PlanarPentagonL01.Branch(pent)[4], pth1.AppendElement(pent));
                }

                for (int pent = 0; pent < component.PlanarPentagonL02.BranchCount; pent++)
                {
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[0], pth1.AppendElement(pent));
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[1], pth1.AppendElement(pent));
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[2], pth1.AppendElement(pent));
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[3], pth1.AppendElement(pent));
                    All_PentagonPts_L02.Add(component.PlanarPentagonL02.Branch(pent)[4], pth1.AppendElement(pent));
                }

                // Information from Stripe Class
                for (int s = 0; s < component.Stripes.Count; s++)
                {
                    for (int t = 0; t < component.Stripes[s].SurfaceAtLoop.Length; t++)
                    { All_StripeBreps.Add(component.Stripes[s].SurfaceAtLoop[t], pth1.AppendElement(s)); }

                    //for (int u = 0; u < component.Stripes[s].IntersectionCurve.Length; u++)
                    //{ All_StripeIntersectCrvs.Add(component.Stripes[s].IntersectionCurve[u], pth1.AppendElement(s));}

                    All_StripeIntersectPlane.Add(component.Stripes[s].IntersectionPlane, pth1.AppendElement(s));
                }

                // ======================================================================================================
                // Gene Added

                for (int s = 0; s < component.StripesSingle.Count; s++)
                {
                    All_SingleStripeBreps.Add(component.StripesSingle[s].loop, pth1.AppendElement(s));

                    //for (int u = 0; u < component.Stripes[s].IntersectionCurve.Length; u++)
                    //{ All_StripeIntersectCrvs.Add(component.Stripes[s].IntersectionCurve[u], pth1.AppendElement(s));}

                    //All_StripeIntersectPlane.Add(component.StripesSingle[s].IntersectionPlane, pth1.AppendElement(s));
                }

                // ======================================================================================================

                componentIdx++;
            }

            //---- End Functions ------------------------------------------------------------------------
            //---- Set Output ---------------------------------------------------------------------------

            DA.SetDataTree(0, All_CentrePointsL01);
            DA.SetDataTree(1, All_CentrePointsL02);
            DA.SetDataTree(2, All_Curves);
            DA.SetDataTree(3, All_PlateCrv);
            DA.SetDataTree(4, All_PentagonPts_L01);
            DA.SetDataTree(5, All_PentagonPts_L02);
            DA.SetDataTree(6, All_StripeIds);
            DA.SetDataTree(7, All_StripeBreps);
            DA.SetDataTree(8, All_StripeIntersectPlane);

            //// =======================================================================================
            // Added by Gene

            DA.SetDataTree(9, All_ExtendedCurves);
            DA.SetDataTree(10, All_SingleStripeBreps);
            //// =======================================================================================

            //---- End Set Output -----------------------------------------------------------------------
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //---- Declareing ---------------------------------------------------------------------------
            GH_Structure<GH_Brep> AllStripes;
            DA.GetDataTree("Triloop Stipes", out AllStripes);

            GH_Structure<GH_Point> AllPoints;
            DA.GetDataTree("Points", out AllPoints);

            bool Reorient = false;
            DA.GetData<bool>("Merge Stripes", ref Reorient);

            bool Switch = false;
            DA.GetData<bool>("Switch", ref Switch);

            int Seam = 0;
            DA.GetData<int>("Seam", ref Seam);

            DataTree<Brep> AllUnrolledBreps = new DataTree<Brep>();
            DataTree<Brep> ForReorientBreps = new DataTree<Brep>();
            DataTree<Plane> AllOrientPlanes = new DataTree<Plane>();
            DataTree<Curve> AllSharedCurves = new DataTree<Curve>();
            DataTree<Point3d> AllUnrolledPoints = new DataTree<Point3d>();

            //---- End Declareing -----------------------------------------------------------------------
            //---- Functions ----------------------------------------------------------------------------

            #region Unroll

            for (int i = 0; i < AllStripes.Branches.Count; i++)
            {
                GH_Path pth = new GH_Path(i);
                GH_Path originalPath = AllStripes.Paths[i];
                int stripecounter = 0;

                foreach (GH_Brep gbrep in AllStripes[i])
                {
                    Unroller unroll = new Unroller(gbrep.Value);
                    // Add points to unroll with
                    if (AllPoints.Branches.Count != 0)
                    {
                        foreach (GH_Point pt in AllPoints[i])
                        { unroll.AddFollowingGeometry(pt.Value); }
                    }

                    unroll.ExplodeOutput = false;

                    Curve[] curves;
                    Point3d[] unrolledPoints;
                    TextDot[] dots;
                    Brep[] unrolledBreps = unroll.PerformUnroll(out curves, out unrolledPoints, out dots);

                    if (Reorient == false)
                    {
                        foreach (Brep b in unrolledBreps)
                        { AllUnrolledBreps.Add(b, originalPath); }

                        foreach (Point3d p in unrolledPoints)
                        { AllUnrolledPoints.Add(p, originalPath); }
                    }

                    else
                    {
                        foreach (Brep b in unrolledBreps)
                        { AllUnrolledBreps.Add(b, pth.AppendElement(stripecounter)); }
                    }

                    // For reorientation
                    if (Reorient == true)
                    { ForReorientBreps.Add(unrolledBreps[Seam], pth); }

                    stripecounter++;
                }
            }
            #endregion unroll

            if (Reorient == true)
            {
                //ForReorientBreps.Branch(0)[0].Curves3D[0].PointAtEnd;

                for (int i = 0; i < ForReorientBreps.BranchCount; i++)
                {
                    GH_Path pth = new GH_Path(i);

                    foreach (Curve crv0 in ForReorientBreps.Branch(i)[0].Curves3D)
                    {
                        foreach (Curve crv1 in ForReorientBreps.Branch(i)[1].Curves3D)
                        {
                            double l0 = crv0.GetLength();
                            double l1 = crv1.GetLength();

                            if (Math.Abs(l0 - l1) < 0.00001)
                            {

                                // orient crv0
                                Plane origin0 = new Plane(new Point3d(0, 0, 0), new Vector3d(1, 0, 0), new Vector3d(0, 1, 0));
                                Plane target0 = new Plane(origin0);
                                AllOrientPlanes.Add(origin0, pth.AppendElement(0));
                                AllOrientPlanes.Add(target0, pth.AppendElement(0));

                                // orient crv1
                                Vector3d vect0 = crv1.TangentAtStart;
                                Vector3d vect1 = Vector3d.CrossProduct(vect0, new Vector3d(0.0, 0.0, 1.0));
                                Plane origin1 = new Plane(crv1.PointAtStart, vect0, vect1);

                                Vector3d vect2 = new Vector3d();
                                Vector3d vect3 = new Vector3d();
                                Plane target1 = new Plane();

                                if (Switch == true)
                                {
                                    vect2 = crv0.TangentAtStart;
                                    vect3 = Vector3d.CrossProduct(vect2, new Vector3d(0.0, 0.0, 1.0));
                                    target1 = new Plane(crv0.PointAtStart, vect2, vect3);
                                }

                                else
                                {
                                    vect2 = crv0.TangentAtStart;
                                    vect3 = Vector3d.CrossProduct(-vect2, new Vector3d(0.0, 0.0, 1.0));
                                    target1 = new Plane(crv0.PointAtEnd, -vect2, vect3);
                                }

                                AllOrientPlanes.Add(origin1, pth.AppendElement(1));
                                AllOrientPlanes.Add(target1, pth.AppendElement(1));
                                // shared curve of stripe0 and stripe 1
                                AllSharedCurves.Add(crv0, pth.AppendElement(0));
                                AllSharedCurves.Add(crv1, pth.AppendElement(0));

                            }
                        }

                        // orient crv2
                        foreach (Curve crv2 in ForReorientBreps.Branch(i)[2].Curves3D)
                        {
                            double l0 = crv0.GetLength();
                            double l1 = crv2.GetLength();

                            if (Math.Abs(l0 - l1) < 0.00001)
                            {
                                Vector3d vect0 = crv2.TangentAtStart;
                                Vector3d vect1 = Vector3d.CrossProduct(vect0, new Vector3d(0.0, 0.0, 1.0));
                                Plane origin2 = new Plane(crv2.PointAtStart, vect0, vect1);

                                Vector3d vect2 = new Vector3d();
                                Vector3d vect3 = new Vector3d();
                                Plane target2 = new Plane();

                                if (Switch == true)
                                {
                                    vect2 = crv0.TangentAtStart;
                                    vect3 = Vector3d.CrossProduct(vect2, new Vector3d(0.0, 0.0, 1.0));
                                    target2 = new Plane(crv0.PointAtStart, vect2, vect3);
                                }

                                else
                                {
                                    vect2 = crv0.TangentAtStart;
                                    vect3 = Vector3d.CrossProduct(-vect2, new Vector3d(0.0, 0.0, 1.0));
                                    target2 = new Plane(crv0.PointAtEnd, -vect2, vect3);
                                }

                                AllOrientPlanes.Add(origin2, pth.AppendElement(2));
                                AllOrientPlanes.Add(target2, pth.AppendElement(2));
                                // shared curve of stripe0 and stripe 2
                                AllSharedCurves.Add(crv2, pth.AppendElement(2));
                                AllSharedCurves.Add(crv0, pth.AppendElement(2));
                            }
                        }

                    }
                    // find the shared curve oft stripe 1 and stripe 2
                    foreach (Curve crv1 in ForReorientBreps.Branch(i)[1].Curves3D)
                    {
                        foreach (Curve crv2 in ForReorientBreps.Branch(i)[2].Curves3D)
                        {
                            double l1 = crv1.GetLength();
                            double l2 = crv2.GetLength();

                            // shared curve of stripe1 and stripe 2
                            if (Math.Abs(l1 - l2) < 0.00001)
                            {
                                AllSharedCurves.Add(crv1, pth.AppendElement(1));
                                AllSharedCurves.Add(crv2, pth.AppendElement(1));
                            }

                        }

                    }
                }

            }

            //---- End Functions --------------------------------------------------------------------------
            //----Set Output-------------------------------------------------------------------------------

            DA.SetDataTree(0, AllUnrolledBreps);
            DA.SetDataTree(1, AllOrientPlanes);
            DA.SetDataTree(2, AllSharedCurves);
            DA.SetDataTree(3, AllUnrolledPoints);

            //----End Set Output---------------------------------------------------------------------------
        }
        private void createStripe(int firstVertexIndex, int secondVertexIndex, int thirdVertexIndex, GH_Path path, int item)
        {
            // first vertex in the stripe direction
            Point3d a = bottomCps[firstVertexIndex];
            Point3d A = topCps[firstVertexIndex];

            Point3d b = bottomCps[secondVertexIndex];
            Point3d B = topCps[secondVertexIndex];

            Point3d c = bottomCps[thirdVertexIndex];
            Point3d C = topCps[thirdVertexIndex];

            // Centre of Edge AB
            Point3d ab = 0.5 * (a + b);
            Point3d AB = 0.5 * (A + B);

            // Centre of Edge AC
            Point3d ac = 0.5 * (a + c);
            Point3d AC = 0.5 * (A + C);

            // Centre of Mesh Face
            Point3d m = (ab + ac + 0.5 * (b + c)) / 3;
            Point3d M = (AB + AC + 0.5 * (B + C)) / 3;

            // perform planar Offset
            double planarOffset = planarVerticesValues[firstVertexIndex];
            double curveScaler = curveVerticesValues[firstVertexIndex];
            double openingScaler = openingWidthVerticesValues[firstVertexIndex];
            double curvePointiness = pointinessValues[firstVertexIndex];

            if (ManualAdjustedVertexIndexies.Contains(firstVertexIndex))
            {
                GH_Path pth = new GH_Path(firstVertexIndex);

                planarOffset = ManualValueTree[new GH_Path(firstVertexIndex)][2].Value;
                curveScaler = ManualValueTree[new GH_Path(firstVertexIndex)][0].Value;
                openingScaler = ManualValueTree[new GH_Path(firstVertexIndex)][3].Value;
                curvePointiness = ManualValueTree[new GH_Path(firstVertexIndex)][1].Value;

            }

            // Offset : Centre of Edge AB
            Vector3d v_ab = a - b;
            Vector3d v_AB = A - B;
            v_ab.Unitize();
            v_AB.Unitize();

            // Offset : Centre of Edge AC
            Vector3d v_ac = a - c;
            Vector3d v_AC = A - C;
            v_ac.Unitize();
            v_AC.Unitize();

            // not used
            #region Correct Offset
            /*

            // Angles
            Vector3d ac_ab = ac - ab; ac_ab.Unitize();
            Vector3d AC_AB = AC - AB; AC_AB.Unitize();

            double dotProduct_b = ac_ab * v_ab;
            double dotProduct_B = AC_AB * v_AB;
            double dotProduct_c = -ac_ab * v_ac;
            double dotProduct_C = -AC_AB * v_AC;

            Utils.ToDegree(dotProduct_b);
            Utils.ToDegree(dotProduct_B);
            Utils.ToDegree(dotProduct_c);
            Utils.ToDegree(dotProduct_C);

            v_ab *= planarOffset / Math.Tan(Math.Acos(dotProduct_b));
            v_AB *= planarOffset / Math.Tan(Math.Acos(dotProduct_B));
            v_ac *= planarOffset / Math.Tan(Math.Acos(dotProduct_c));
            v_AC *= planarOffset / Math.Tan(Math.Acos(dotProduct_C));

            */
            #endregion correct offset

            // create offset point
            Point3d oab = ab + (v_ab * planarOffset);
            Point3d oAB = AB + (v_AB * planarOffset);

            // create offset point
            Point3d oac = ac + (v_ac * planarOffset);
            Point3d oAC = AC + (v_AC * planarOffset);

            //---- Super normalization of Offset Points ----------------------------------------------------------------------------

            // shortest connected Edge (changes offset point; normalize offset point)
            if (iSuperNormalization == true)
            {
                List<int> neighbourVertices = iSpringMesh.Vertices[firstVertexIndex].NeighborVertexIndices;
                double minimalLengthTop = 999999999999;
                double minimalLengthBottom = 9999999999999;

                foreach (int i in neighbourVertices)
                {
                    Vector3d vectorBottom = bottomCps[firstVertexIndex] - bottomCps[i];
                    Vector3d vectorTop = topCps[firstVertexIndex] - topCps[i];

                    if (vectorBottom.Length * 0.5 < minimalLengthBottom)
                        minimalLengthBottom = vectorBottom.Length * 0.5;

                    if (vectorTop.Length * 0.5 < minimalLengthTop)
                        minimalLengthTop = vectorTop.Length * 0.5;
                }
                //Test:
                minimalLengthBottom = (minimalLengthTop + minimalLengthBottom) * 0.5;
                minimalLengthTop = minimalLengthBottom;
                //End Test

                oab = a - (v_ab * (minimalLengthBottom - planarOffset));
                oAB = A - (v_AB * (minimalLengthTop - planarOffset));

                oac = a - (v_ac * (minimalLengthBottom - planarOffset));
                oAC = A - (v_AC * (minimalLengthTop - planarOffset));
            }

            //---- End Super normalization of Offset Points ----------------------------------------------------------------------------

            Point3d AAB = curveScaler * A + (1.0 - curveScaler) * oAB;
            Point3d aab = curveScaler * a + (1.0 - curveScaler) * oab;

            Point3d AAC = curveScaler * A + (1.0 - curveScaler) * oAC;
            Point3d aac = curveScaler * a + (1.0 - curveScaler) * oac;

            Point3d openingAAB = (-1 * v_AB * openingScaler) + A;
            Point3d openingaab = (-1 * v_ab * openingScaler) + a;

            Point3d openingAAC = (-1 * v_AC * openingScaler) + A;
            Point3d openingaac = (-1 * v_ac * openingScaler) + a;

            // Condition, choose between Opening Width and tangentscale

            if (new Vector3d(AAB - A).Length > openingScaler)
                AAB = openingAAB;

            if (new Vector3d(aab - a).Length > openingScaler)
                aab = openingaab;

            if (new Vector3d(AAC - A).Length > openingScaler)
                AAC = openingAAC;

            if (new Vector3d(aac - a).Length > openingScaler)
                aac = openingaac;

            // Pointiness of the Surface

            Point3d max_aA = 0.5 * (a + A);
            Point3d min_aA1 = 0.5 * (aab + AAB);
            Point3d min_aA2 = 0.5 * (aac + AAC);
            Point3d aA1 = (curvePointiness * max_aA) + ((1 - curvePointiness) * min_aA1);
            Point3d aA2 = (curvePointiness * max_aA) + ((1 - curvePointiness) * min_aA2);

            // Create Curves
            Curve profileCurve1 = Curve.CreateControlPointCurve(new List<Point3d>() { oab, aab, aA1, AAB, oAB }, curveDegree);
            Curve profileCurve2 = Curve.CreateControlPointCurve(new List<Point3d>() { oac, aac, aA2, AAC, oAC }, curveDegree);
            Curve profileCrv11 = Curve.CreateControlPointCurve(new List<Point3d>() { ab, oab }, 1);
            Curve profileCrv12 = Curve.CreateControlPointCurve(new List<Point3d>() { oAB, AB }, 1);
            Curve profileCrv21 = Curve.CreateControlPointCurve(new List<Point3d>() { ac, oac }, 1);
            Curve profileCrv22 = Curve.CreateControlPointCurve(new List<Point3d>() { oAC, AC }, 1);

            Curve profileCurveNew1 = Curve.JoinCurves(new List<Curve>() { profileCrv11, profileCurve1, profileCrv12 }, documentTolerance, true)[0];
            Curve profileCurveNew2 = Curve.JoinCurves(new List<Curve>() { profileCrv21, profileCurve2, profileCrv22 }, documentTolerance, true)[0];

            oTriLoopCurves.Add(profileCurveNew1, path.AppendElement(item));
            oTriLoopCurves.Add(profileCurveNew2, path.AppendElement(item));

            if (iPolySrf)
            {
                //not used method : if triloop need to be polySurface.
                #region Genes Method
                /*
                PolyCurve polyCurve1 = new PolyCurve();
                polyCurve1.Append(new LineCurve(m, ab));
                polyCurve1.Append(new LineCurve(ab, oab));
                polyCurve1.Append(profileCurve1);
                polyCurve1.Append(new LineCurve(oAB, AB));
                polyCurve1.Append(new LineCurve(AB, M));

                PolyCurve polyCurve2 = new PolyCurve();
                polyCurve2.Append(new LineCurve(m, ac));
                polyCurve2.Append(new LineCurve(ac, oac));
                polyCurve2.Append(profileCurve2);
                polyCurve2.Append(new LineCurve(oAC, AC));
                polyCurve2.Append(new LineCurve(AC, M));

                oTriLoop.Add(
                    Brep.CreateFromLoft(
                       new List<Curve>() { polyCurve1, polyCurve2 },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       )[0], path.AppendElement(item)
                   );

                */
                #endregion Genes Method

                //used method
                #region Seperate Planar from Curved Method
                PolyCurve polyCurve1 = new PolyCurve();
                polyCurve1.Append(profileCurve1);

                PolyCurve polyCurve2 = new PolyCurve();
                polyCurve2.Append(profileCurve2);

                // Planar Part Curves
                Curve planarCurveBottom = Curve.CreateControlPointCurve(new List<Point3d>() { m, ac, oac, oab, ab, m }, 1);
                Curve planarCurveTop = Curve.CreateControlPointCurve(new List<Point3d>() { M, AB, oAB, oAC, AC, M }, 1);

                // Add Planar Crv
                oTriLoopPlanCrv.Add(planarCurveBottom, path.AppendElement(item));
                oTriLoopPlanCrv.Add(planarCurveTop, path.AppendElement(item));

                // Add Bended Brep
                oTriLoop.Add(
                    Brep.CreateFromLoft(
                       new List<Curve>() { polyCurve1, polyCurve2 },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       )[0], path.AppendElement(item)
                   );
                #endregion Seperate Planar from Curved Method

            }
            else
            #region single surface
            {
                profileCurve1 = Curve.JoinCurves(
                    new List<Curve>() { new LineCurve(b, oab), profileCurve1, new LineCurve(oAB, B) },
                    documentTolerance,
                    true)[0];

                profileCurve2 = Curve.JoinCurves(
                    new List<Curve>() { new LineCurve(c, oac), profileCurve2, new LineCurve(oAC, C) },
                    documentTolerance,
                    true)[0];

                // Planar Part Curves
                Curve planarCurveBottom = Curve.CreateControlPointCurve(new List<Point3d>() { m, ac, oac, oab, ab, m }, 1);
                Curve planarCurveTop = Curve.CreateControlPointCurve(new List<Point3d>() { M, AB, oAB, oAC, AC, M }, 1);
                // Add Planar Crvs
                oTriLoopPlanCrv.Add(planarCurveBottom, path.AppendElement(item));
                oTriLoopPlanCrv.Add(planarCurveTop, path.AppendElement(item));

                Brep brep = Brep.CreateFromLoft(
                       new List<Curve>() { profileCurve1, profileCurve2 },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       )[0];

                // =============================================
                // Trim the brep using planes
                // =============================================

                double offsetAmount = 0.2;
                Vector3d normal;
                Brep[] breps;

                normal = Vector3d.CrossProduct(B - A, C - A);

                Point3d A_ = A + offsetAmount * normal;

                breps = brep.Trim(new Plane(A_, AB, M), documentTolerance);
                if (breps.Length > 0) brep = breps[0];
                else { oTriLoop.Add(brep, path.AppendElement(item)); return; }

                breps = brep.Trim(new Plane(A_, M, AC), documentTolerance);
                if (breps.Length > 0) brep = breps[0];
                else { oTriLoop.Add(brep, path.AppendElement(item)); return; }

                normal = Vector3d.CrossProduct(b - a, c - a);

                Point3d a_ = a - offsetAmount * normal;

                breps = brep.Trim(new Plane(a_, m, ab), documentTolerance);
                if (breps.Length > 0) brep = breps[0];
                else { oTriLoop.Add(brep, path.AppendElement(item)); return; }

                breps = brep.Trim(new Plane(a_, ac, m), documentTolerance);
                if (breps.Length > 0) brep = breps[0];
                else { oTriLoop.Add(brep, path.AppendElement(item)); return; }

                oTriLoop.Add(brep, path.AppendElement(item));
            }
            #endregion single surface

            #region close panel

            // close panel
            //Point3d closeVertice = Point3dList.ClosestPointInList(iClosedPanelPts, iSpringMesh.Vertices[firstVertexIndex].Position);
            //if (ICD.Utils.Distance(closeVertice, iSpringMesh.Vertices[firstVertexIndex].Position) < iClosePanelDist)
            if (iVertexPanel2[firstVertexIndex])
            {
                oClosedPanel.Add(
                    Brep.CreateFromLoft(
                       new List<Curve>() { new LineCurve(A, oAB), new LineCurve(A, oAC) },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       )[0], path.AppendElement(item)
                    );
                oClosedPanel.Add(
                    Brep.CreateFromLoft(
                       new List<Curve>() { new LineCurve(oab, a), new LineCurve(oac, a) },
                       Point3d.Unset, Point3d.Unset,
                       LoftType.Normal,
                       false
                       )[0], path.AppendElement(item)
                    );
            }

            #endregion close panel

            // do EffectorHoles
            List<Point3d> EffectorHoleTop = EffectorHoles(A, B, C, M, oAB, oAC, item);
            List<Point3d> EffectorHoleBottom = EffectorHoles(a, b, c, m, oab, oac, item);

            foreach (Point3d pt in EffectorHoleTop)
                oTriLoopEffectorHoles.Add(pt, path.AppendElement(item).AppendElement(1));

            foreach (Point3d pt in EffectorHoleBottom)
                oTriLoopEffectorHoles.Add(pt, path.AppendElement(item).AppendElement(0));
        }