/// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>

        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // First, we need to retrieve all data from the input parameters.
            // When data cannot be extracted from a parameter, we should abort this method.
            if (!DA.GetDataList <Rhino.Geometry.Curve>(0, rhinoCurvesInput))
            {
                return;
            }
            DA.GetData(1, ref segmentLengthInput);
            if (!DA.GetData(2, ref rfemLineSupportInput))
            {
                rfemLineSupportInput.No = -1;
            }
            DA.GetData(3, ref commentsInput);
            DA.GetData(4, ref run);


            // The actual functionality will be in a method defined below. This is where we run it
            if (run == true)
            {
                //clears and resets all output parameters.
                // this is done to ensure that if function is repeadedly run, then parameters are re-read and redefined
                RfemLines.Clear();
                writeSuccess = false;

                RfemLines = CreateRfemLines(rhinoCurvesInput, rfemLineSupportInput, commentsInput);
                DA.SetData(1, writeSuccess);
            }
            else
            {
                // if "run" is set to false, then also the output parameter "success" is set to false
                // this ensures that as soon as "run" toogle is set "false", it automatically updates output.
                DA.SetData(1, false);
            }

            // Finally assign the processed data to the output parameter.
            DA.SetDataList(0, RfemLines);

            //clears and resets all input parameters.
            // this is done to ensure that if function is repeadedly run, then parameters are re-read and redefined
            rhinoCurvesInput.Clear();
            commentsInput        = "";
            rfemLineSupportInput = new Dlubal.RFEM5.LineSupport();
        }
        private List <Dlubal.RFEM5.Line> CreateRfemLines(List <Rhino.Geometry.Curve> Rh_Crv, Dlubal.RFEM5.LineSupport rfemLineSupportMethodIn, string commentsListMethodIn)
        {
            //defining variables needed to store geometry and RFEM info
            Rhino.Geometry.Point3d   startPoint;
            Rhino.Geometry.Point3d   endPoint;
            List <Dlubal.RFEM5.Node> RfemNodeList = new List <Dlubal.RFEM5.Node>();
            List <Dlubal.RFEM5.Line> RfemLineList = new List <Dlubal.RFEM5.Line>();
            string createdLinesList = "";

            //---- Rhino geometry simplification and creating a list of simple straight lines ----
            #region Rhino geometry processing

            //start by reducing the input curves to simple lines with start/end points
            List <Rhino.Geometry.Curve> RhSimpleLines = new List <Rhino.Geometry.Curve>();

            foreach (Rhino.Geometry.Curve RhSingleCurve in Rh_Crv)
            {
                if (RhSingleCurve.IsPolyline())
                {
                    if (RhSingleCurve.SpanCount == 1)
                    {
                        // if line is a simple straight line
                        RhSimpleLines.Add(RhSingleCurve);
                    }
                    else
                    {
                        foreach (Rhino.Geometry.Curve explodedLine in RhSingleCurve.DuplicateSegments())
                        {
                            // if line is polyline, then it gets exploded
                            RhSimpleLines.Add(explodedLine);
                        }
                    }
                }

                else
                {
                    foreach (Rhino.Geometry.Curve explodedLine in RhSingleCurve.ToPolyline(0, 0, 3.14, 1, 0, 0, 0, segmentLengthInput, true).DuplicateSegments())
                    {
                        // if line is a an arc or nurbs or have any curvature, it gets simplified
                        RhSimpleLines.Add(explodedLine);
                    }
                }
            }
            #endregion

            //---- Interface with RFEM, getting available element numbers ----
            #region Gets interface with RFEM and currently available element numbers

            // Gets interface to running RFEM application.
            IApplication app = Marshal.GetActiveObject("RFEM5.Application") as IApplication;
            // Locks RFEM licence
            app.LockLicense();

            // Gets interface to active RFEM model.
            IModel model = app.GetActiveModel();

            // Gets interface to model data.
            IModelData data = model.GetModelData();

            // Gets Max node, line , line support numbers
            int currentNewNodeNo        = data.GetLastObjectNo(ModelObjectType.NodeObject) + 1;
            int currentNewLineNo        = data.GetLastObjectNo(ModelObjectType.LineObject) + 1;
            int currentNewLineSupportNo = data.GetLastObjectNo(ModelObjectType.LineSupportObject) + 1;

            #endregion

            //----- cycling through all lines and creating RFEM objects ----
            #region Creates RFEM node and line elements

            for (int i = 0; i < RhSimpleLines.Count; i++)
            {
                // defining start and end nodes of the line
                Dlubal.RFEM5.Node tempCurrentStartNode = new Dlubal.RFEM5.Node();
                Dlubal.RFEM5.Node tempCurrentEndNode   = new Dlubal.RFEM5.Node();

                startPoint = RhSimpleLines[i].PointAtStart;
                endPoint   = RhSimpleLines[i].PointAtEnd;

                tempCurrentStartNode.No = currentNewNodeNo;
                tempCurrentStartNode.X  = startPoint.X;
                tempCurrentStartNode.Y  = startPoint.Y;
                tempCurrentStartNode.Z  = startPoint.Z;

                tempCurrentEndNode.No = currentNewNodeNo + 1;
                tempCurrentEndNode.X  = endPoint.X;
                tempCurrentEndNode.Y  = endPoint.Y;
                tempCurrentEndNode.Z  = endPoint.Z;

                RfemNodeList.Add(tempCurrentStartNode);
                RfemNodeList.Add(tempCurrentEndNode);

                // defining line
                Dlubal.RFEM5.Line tempCurrentLine = new Dlubal.RFEM5.Line();

                tempCurrentLine.No       = currentNewLineNo;
                tempCurrentLine.Type     = LineType.PolylineType;
                tempCurrentLine.Comment  = commentsListMethodIn;
                tempCurrentLine.NodeList = $"{tempCurrentStartNode.No}, {tempCurrentEndNode.No}";

                RfemLineList.Add(tempCurrentLine);


                // adding line numbers to list with all lines
                if (i == RhSimpleLines.Count)
                {
                    createdLinesList = createdLinesList + currentNewLineNo.ToString();
                }
                else
                {
                    createdLinesList = createdLinesList + currentNewLineNo.ToString() + ",";
                }

                // increasing counters for numbering
                currentNewLineNo++;
                currentNewNodeNo = currentNewNodeNo + 2;
            }
            #endregion

            //----- Writing nodes and lines to RFEM ----
            #region Write nodes, lines and supports to RFEM

            try
            {
                // modification - set model in modification mode, new information can be written
                data.PrepareModification();

                //This version writes lines one-by-one because the data.SetNodes() for array appears not to be working
                //data.SetNodes(RfemNodeArray);
                foreach (Node currentRfemNode in RfemNodeList)
                {
                    data.SetNode(currentRfemNode);
                }

                //This version writes lines one-by-one because the data.SetLines() for array appears not to be working
                foreach (Dlubal.RFEM5.Line currentRfemLine in RfemLineList)
                {
                    data.SetLine(currentRfemLine);
                }

                //Definition of line supports - only is there is input for support:
                if (rfemLineSupportInput.No != -1)
                {
                    rfemLineSupportMethodIn.No       = currentNewLineSupportNo;
                    rfemLineSupportMethodIn.LineList = createdLinesList;
                    data.SetLineSupport(ref rfemLineSupportMethodIn);
                }

                // finish modification - RFEM regenerates the data
                data.FinishModification();
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error - Line Write", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            #endregion


            // Releases interface to RFEM model.
            #region Releases interface to RFEM

            model = null;

            // Unlocks licence and releases interface to RFEM application.
            if (app != null)
            {
                app.UnlockLicense();
                app = null;
            }

            // Cleans Garbage Collector and releases all cached COM interfaces.
            System.GC.Collect();
            System.GC.WaitForPendingFinalizers();


            #endregion

            //output 'success' as true and return the list of the lines;
            writeSuccess = true;
            return(RfemLineList);
        }