//using FeMM.Common.Models;
//using FeMM.Grasshopper.DataTypes.FeMM;
//using FeMM.Grasshopper.Helpers;
//using GH_IO.Serialization;
//using Grasshopper.Kernel;
//using Grasshopper.Kernel.Parameters;
//using Grasshopper.Kernel.Special;
//using Rhino.Geometry;
//using System;
//using System.Collections.Generic;
//using System.Diagnostics;
//using System.IO;
//using System.Linq;
//using System.Reflection;
//using System.Text;
//using System.Windows.Forms;

//namespace FeMM.Grasshopper.Components.Analysis
//{
//    public class StrausAnalysisComponent : GH_Component
//    {
//        protected bool _run;
//        private GH_Model _model;
//        private bool _just_loaded;

//        /// <summary>
//        /// Initializes a new instance of the StrausAnalysisComponent class.
//        /// </summary>
//        public StrausAnalysisComponent()
//          : base("Straus Analysis", "SA", "Model Analisys with Straus7", CategoryNameConstants.CATEGORY_FEMM, CategoryNameConstants.SUBCATEGORY_ANALYSIS)
//        {
//            _run = false;
//            _model = new GH_Model();
//            _just_loaded = false;
//        }

//        public override void CreateAttributes()
//        {
//            ComponentAttributes.ComponentOneButtonAttributes attr = new ComponentAttributes.ComponentOneButtonAttributes(this, "Run");
//            attr.ButtonPressed += () =>
//            {
//                _run = true;
//                ExpireSolution(true);
//            };
//            m_attributes = attr;
//        }

//        /// <summary>
//        /// Registers all the input parameters for this component.
//        /// </summary>
//        protected override void RegisterInputParams(GH_InputParamManager pManager)
//        {
//            pManager.AddGenericParameter("Model", "M", "The FEM model", GH_ParamAccess.item);
//            pManager.AddIntegerParameter("Solver", "ST", "The type of solver to use", GH_ParamAccess.item, 0);
//            Param_Integer solverParam = (Param_Integer)pManager[1];
//            for (int i = 0; i < Common.Helpers.StrausHelper.Solvers.Length; i++)
//                solverParam.AddNamedValue(Common.Helpers.StrausHelper.Solvers[i], i);
//            pManager.AddTextParameter("Analysis Results", "AR", "The analysis result cases or combination to returns", GH_ParamAccess.list);
//            pManager[2].Optional = true;
//            pManager.AddTextParameter("Output Path", "O", "The full path of the file model to create", GH_ParamAccess.item);
//            pManager.AddTextParameter("API Server IP", "IP", "The IP of the machine where runs the API server", GH_ParamAccess.item, "localhost");
//            int n = pManager.AddBooleanParameter("Keep Running", "K", "Run analysis automatically when input is chaged", GH_ParamAccess.item, false);
//            pManager[n].Optional = true;
//        }

//        /// <summary>
//        /// Registers all the output parameters for this component.
//        /// </summary>
//        protected override void RegisterOutputParams(GH_OutputParamManager pManager)
//        {
//            pManager.AddGenericParameter("Model", "M", "The FEM model", GH_ParamAccess.item);
//        }

//        /// <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)
//        {
//            Message = "";
//            GH_Model model = null;
//            int solver = 0;
//            string outputPath = "";
//            string ip = "";
//            bool keepRunning = false;
//            if (!DA.GetData("Model", ref model))
//                return;
//            if (!DA.GetData("Solver", ref solver))
//                return;
//            if (!DA.GetData("Output Path", ref outputPath))
//                return;
//            if (!DA.GetData("API Server IP", ref ip))
//                return;
//            DA.GetData("Keep Running", ref keepRunning);

//            if (Path.GetExtension(outputPath).ToLower() != ".st7")
//            {
//                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid extension in file name");
//                return;
//            }

//            // Retrieve all te load cases used in the model
//            Common.Helpers.ModelHelper.GetLoadCases(model.Value, out List<LoadCaseModel> loadCases);

//            // Connect the ValueList component on the analysis results input item
//            IEnumerable<IGH_Param> keys_analysisResultLists = Params.Input[2].Sources.
//                Where(s => s.GetType() == typeof(GH_ValueList));
//            foreach (GH_ValueList vallist in keys_analysisResultLists)
//            {
//                if (vallist.ListMode != GH_ValueListMode.CheckList)
//                    vallist.ListMode = GH_ValueListMode.CheckList;

//                List<string> names = loadCases.Select(lc => lc.Name).Distinct().ToList();
//                names.AddRange(model.Value.Combinations.Select(c => c.Name));
//                ComponentsHelper.SetValueList(vallist, names);
//                vallist.NickName = "Results";
//            }

//            List<string> analysisCaseResults = new List<string>();
//            List<LoadCaseModel> requestedLoadCases = new List<LoadCaseModel>();
//            List<BaseCaseCombinationModel> requestedCombs = new List<BaseCaseCombinationModel>();
//            if (DA.GetDataList("Analysis Results", analysisCaseResults))
//            {
//                foreach (string caseName in analysisCaseResults)
//                {
//                    LoadCaseModel lCase = loadCases.FirstOrDefault(lc => lc.Name == caseName);
//                    BaseCaseCombinationModel cCase = model.Value.Combinations.FirstOrDefault(cc => cc.Name == caseName);
//                    if (lCase != null)
//                    {
//                        requestedLoadCases.Add(lCase);
//                    }
//                    else if (cCase != null)
//                    {
//                        requestedCombs.Add(cCase);
//                        foreach (KeyValuePair<CaseModel, double> kvp in cCase.Values)
//                        {
//                            if (kvp.Value != 0 && requestedLoadCases.FirstOrDefault(lc => lc.Name == kvp.Key.Name) == null)
//                            {
//                                requestedLoadCases.Add(loadCases.Single(lc => lc.Name == kvp.Key.Name));
//                            }
//                        }
//                    }
//                    else
//                    {
//                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"The result case name {caseName} does not exists.");
//                        return;
//                    }
//                }
//            }
//            else
//            {
//                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameter Analysis Results failed to collect data");
//            }

//            if (_run || keepRunning)
//            {
//                if (Common.Helpers.StrausHelper.ConnectService(ip, out St7ApiWrapper.ISt7ApiService ro))
//                {
//                    if (Common.Helpers.StrausHelper.CreateModel(ro, model.Value, outputPath, Rhino.Settings.Tolerance,
//                        out int modelId, out List<string> warnings, out List<string> errors))
//                    {
//                        Dictionary<CaseModel, int> primaryResultCases, secondaryResultCases;
//                        primaryResultCases = new Dictionary<CaseModel, int>();
//                        secondaryResultCases = new Dictionary<CaseModel, int>();

//                        int index = 1;
//                        for (int i = 0; i < loadCases.Count; i++)
//                        {
//                            LoadCaseModel lc = loadCases[i];
//                            if (requestedLoadCases.Contains(lc))
//                            {
//                                // Load cases solved as primary only in linear solver
//                                if (solver == 0)
//                                {
//                                    // We don't consider load cases added only for combinations
//                                    if (analysisCaseResults.Contains(lc.Name))
//                                    {
//                                        primaryResultCases.Add(lc, index);
//                                    }
//                                    index++;
//                                }
//                            }
//                        }
//                        if (solver != 2)
//                        {
//                            for (int i = 0; i < model.Value.Combinations.Count(); i++)
//                            {
//                                BaseCaseCombinationModel c = model.Value.Combinations[i];
//                                if (requestedCombs.Contains(c))
//                                {
//                                    if (solver == 0)
//                                    {
//                                        secondaryResultCases.Add(c, index);
//                                    }
//                                    else if (solver == 1)
//                                    {
//                                        primaryResultCases.Add(c, index);
//                                    }
//                                }
//                                index++; // Combinations are always resolved
//                            }
//                        }
//                        else
//                        {
//                            for (int i = 0; i < model.Value.StagedConstruction.Count; i++)
//                            {
//                                if (model.Value.StagedConstruction[i] is StagedConstructionCombinationModel sc)
//                                {
//                                    for (int j = 0; j < sc.LoadCombinations.Count; j++)
//                                    {
//                                        LoadCaseCombinationModel c = sc.LoadCombinations[j];
//                                        c.Name += $" [{sc.Name}]";
//                                        primaryResultCases.Add(c, index);
//                                        index++;
//                                    }
//                                }
//                            }
//                        }

//                        int st7_solver = 0;
//                        string res_ext = "";
//                        switch (solver)
//                        {
//                            case 0: // Linear solver
//                                    // Select cases for the results
//                                foreach (LoadCaseModel loadCase in loadCases)
//                                {
//                                    if (requestedLoadCases.Contains(loadCase))
//                                        ro.EnableLSALoadCase(modelId, Convert.ToInt32(loadCase.Id), 1);
//                                    else
//                                        ro.DisableLSALoadCase(modelId, Convert.ToInt32(loadCase.Id), 1);
//                                }
//                                st7_solver = ro.Const("stLinearStaticSolver");
//                                res_ext = "lsa";
//                                break;
//                            case 1: // Nonlinear solver
//                                st7_solver = ro.Const("stNonlinearStaticSolver");
//                                res_ext = "nla";
//                                break;
//                            case 2: // Staged analysis
//                                st7_solver = ro.Const("stNonlinearStaticSolver");
//                                res_ext = "nla";
//                                ro.SetNLAStagedAnalysis(modelId, (byte)ro.Const("btTrue"));
//                                break;
//                        }

//                        if (ro.SaveFile(modelId))
//                        {
//                            Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.FullName.StartsWith("FeMM.Common")).First();
//                            string support_path = Path.GetDirectoryName(assembly.Location);

//                            ProcessStartInfo pInfo = new ProcessStartInfo
//                            {
//                                FileName = Path.Combine(support_path, "St7Solver.exe"),
//                                Arguments = string.Format("\"{0}\" {1}", outputPath, solver)
//                            };

//                            if (!File.Exists(pInfo.FileName))
//                            {
//                                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Cannot find the ST7 solver wrapper");
//                                Message = "Error";
//                            }
//                            else
//                            {
//                                Process p = Process.Start(pInfo);
//                                // Wait for the process to end.
//                                p.WaitForExit();

//                                if (p.ExitCode == 0) // Analysis terminated with success
//                                {
//                                    // Create a deep copy of the model where to add the results
//                                    _model = (GH_Model)model.Duplicate();
//                                    if (_model.Value.Name == "")
//                                        _model.Value.Name = Path.GetFileNameWithoutExtension(outputPath);

//                                    string result_path = Path.Combine(Path.GetDirectoryName(outputPath),
//                                        Path.GetFileNameWithoutExtension(outputPath) + "." + res_ext);
//                                    int numPrimary = 0, numSecondary = 0;

//                                    if (ro.OpenResultFile(modelId, result_path, null, (byte)ro.Const("btTrue"),
//                                        ref numPrimary, ref numSecondary))
//                                    {
//                                        foreach (KeyValuePair<CaseModel, int> kvp in primaryResultCases)
//                                        {
//                                            SetResults(ro, modelId, kvp.Value, kvp.Key);
//                                        }
//                                        foreach (KeyValuePair<CaseModel, int> kvp in secondaryResultCases)
//                                        {
//                                            SetResults(ro, modelId, kvp.Value, kvp.Key);
//                                        }

//                                        ro.CloseResultFile(modelId);
//                                    }
//                                }
//                                else
//                                {
//                                    string err = "";
//                                    if (p.ExitCode < 1000)
//                                        err = ro.GetAPIErrorString(p.ExitCode);
//                                    else
//                                        err = ro.GetSolverErrorString(p.ExitCode);
//                                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, string.Format("Solver error: {0}", err));
//                                    Message = "Error";
//                                }
//                            }
//                        }
//                        ro.CloseFile(modelId);
//                        Message = "Done";
//                    }
//                    else
//                    {
//                        Message = "Error";
//                    }

//                    foreach (string warning in warnings)
//                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, warning);

//                    foreach (string error in errors)
//                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, error);
//                }
//                else
//                {
//                    Message = "Connection Error";
//                }

//                Common.Helpers.StrausHelper.DisconnectService();

//                _run = false;
//            }

//            DA.SetData(0, _model);
//        }

//        private string GetResultCaseName(St7ApiWrapper.ISt7ApiService ro, int modelId, int resultCase)
//        {
//            StringBuilder sb = new StringBuilder(ro.Const("kMaxStrLen"));
//            ro.GetResultCaseName(modelId, resultCase, ref sb, sb.Capacity);
//            string caseName = sb.ToString();
//            return caseName.Substring(caseName.IndexOf(':') + 1).Trim();
//        }

//        private void SetResults(St7ApiWrapper.ISt7ApiService ro, int modelId, int resultCase, CaseModel caseModel)
//        {
//            string resultName = GetResultCaseName(ro, modelId, resultCase);
//            // Sanity check
//            if (!resultName.StartsWith(caseModel.Name))
//            {
//                throw new NotSupportedException("Error reading results of case " + caseModel.Name);
//            }
//            for (int i = 0; i < _model.Value.Nodes.Count; i++)
//            {
//                NodeModel node = _model.Value.Nodes[i];
//                double[] results = new double[6];
//                if (ro.GetNodeResult(modelId, ro.Const("rtNodeDisp"), i + 1, resultCase, ref results))
//                {
//                    NodeDisplResultModel displ = new NodeDisplResultModel(caseModel)
//                    {
//                        Displacement = new Vector3d(results[0], results[1], results[2]),
//                        Rotation = new Vector3d(results[3], results[4], results[5])
//                    };
//                    node.Results.Add(displ);
//                }

//                if (ro.GetNodeResult(modelId, ro.Const("rtNodeReact"), i + 1, resultCase, ref results))
//                {
//                    NodeReactResultModel react = new NodeReactResultModel(caseModel)
//                    {
//                        Force = new Vector3d(results[0], results[1], results[2]),
//                        Moment = new Vector3d(results[3], results[4], results[5])
//                    };
//                    node.Results.Add(react);
//                }
//            }

//            for (int i = 0; i < _model.Value.Beams.Count; i++)
//            {
//                BeamModel beam = _model.Value.Beams[i];
//                int ns = 0, nc = 0;
//                double[] pos = new double[ro.Const("kMaxBeamResult")];
//                double[] res = new double[ro.Const("kMaxBeamResult")];

//                BeamOutputStationsModel.AttributeData modifier = BeamOutputStationsModel.GetModifiers(beam);
//                int stationNumber = 5;
//                if (modifier != null)
//                    stationNumber = modifier.MinimumNumberOfStations;

//                if (ro.GetBeamResultArray(modelId, ro.Const("rtBeamForce"), ro.Const("stBeamPrincipal"), i + 1, stationNumber, resultCase, ref ns, ref nc, ref pos, ref res))
//                {
//                    List<BeamForceResultModel> listBuffer = new List<BeamForceResultModel>();
//                    for (int s = 0; s < ns; s++)
//                    {
//                        double shear1 = res[s * nc + ro.Const("ipBeamSF1")];
//                        double shear2 = res[s * nc + ro.Const("ipBeamSF2")];
//                        double bending1 = res[s * nc + ro.Const("ipBeamBM1")];
//                        double bending2 = res[s * nc + ro.Const("ipBeamBM2")];
//                        if (Common.Helpers.StrausHelper.RotateOf90Deg(beam))
//                        {
//                            double buffer = shear2;
//                            shear2 = shear1;
//                            shear1 = -buffer;
//                            buffer = bending2;
//                            bending2 = bending1;
//                            bending1 = -buffer;
//                        }
//                        BeamForceResultModel result = new BeamForceResultModel(caseModel, pos[s], 0, "")
//                        {
//                            ShearForce = new Vector2d(shear1, shear2),
//                            BendingMoment = new Vector2d(bending1, bending2),
//                            AxialForce = res[s * nc + ro.Const("ipBeamAxialF")],
//                            Torque = res[s * nc + ro.Const("ipBeamTorque")]
//                        };
//                        listBuffer.Add(result);
//                    }

//                    var ll = listBuffer.OrderBy(f => f.Station).ToArray();
//                    for (int j = 0; j < ll.Length; j++)
//                        beam.Results.Add(ll[j]);
//                }
//            }

//            for (int j = 0; j < _model.Value.Plates.Count; j++)
//            {
//                PlateModel plate = _model.Value.Plates[j];
//                int numPoints = 0;
//                int numColumns = 0;
//                double[] results = new double[ro.Const("kMaxPlateResult")];

//                int average = ro.Const("AtNodesAverageNever");
//                int plane = ro.Const("psPlateMidPlane");

//                int plateId = j + 1;
//                int[] buffer = new int[ro.Const("kMaxElementNode")];
//                ro.GetElementConnection(modelId, ro.Const("tyPLATE"), plateId, ref buffer);
//                int[] nodes = new int[buffer[0]];

//                for (int i = 0; i < nodes.Length; i++)
//                {
//                    nodes[i] = buffer[i + 1];
//                }

//                //Plate moment
//                Vector3d[] m = new Vector3d[nodes.Length];
//                if (ro.GetPlateResultArray(modelId, ro.Const("rtPlateMoment"), ro.Const("stPlateLocal"), plateId, resultCase, average, plane, 0, ref numPoints, ref numColumns, ref results))
//                {
//                    for (int i = 0; i < numPoints; i++)
//                    {
//                        m[i] = new Vector3d(results[i * numColumns + ro.Const("ipPlateLocalxx")], results[i * numColumns + ro.Const("ipPlateLocalyy")], results[i * numColumns + ro.Const("ipPlateLocalxy")]);
//                    }

//                    //Principal moments
//                    double[] mMax, mMin, mAngle;

//                    mMax = new double[nodes.Length];
//                    mMin = new double[nodes.Length];
//                    mAngle = new double[nodes.Length];
//                    results = new double[ro.Const("kMaxPlateResult")];

//                    if (ro.GetPlateResultArray(modelId, ro.Const("rtPlateMoment"), ro.Const("stPlateCombined"), plateId, resultCase, average, plane, 0, ref numPoints, ref numColumns, ref results))
//                    {
//                        for (int i = 0; i < numPoints; i++)
//                        {
//                            mMax[i] = results[i * numColumns + ro.Const("ipPlateCombPrincipal11")];
//                            mMin[i] = results[i * numColumns + ro.Const("ipPlateCombPrincipal22")];
//                            mAngle[i] = results[i * numColumns + ro.Const("ipPlateCombPrincipalAngle")];
//                        }
//                        //Axial forces
//                        Vector3d[] f = new Vector3d[nodes.Length];
//                        Vector2d[] shear = new Vector2d[nodes.Length];
//                        results = new double[ro.Const("kMaxPlateResult")];
//                        if (ro.GetPlateResultArray(modelId, ro.Const("rtPlateForce"), ro.Const("stPlateLocal"), plateId, resultCase, average, plane, 0, ref numPoints, ref numColumns, ref results))
//                        {
//                            for (int i = 0; i < numPoints; i++)
//                            {
//                                f[i] = new Vector3d(results[i * numColumns + ro.Const("ipPlateLocalxx")], results[i * numColumns + ro.Const("ipPlateLocalyy")], results[i * numColumns + ro.Const("ipPlateLocalxy")]);
//                                shear[i] = new Vector2d(results[i * numColumns + ro.Const("ipPlateLocalxz")], results[i * numColumns + ro.Const("ipPlateLocalyz")]);
//                            }

//                            //Principal axial forces
//                            double[] fMax = new double[nodes.Length];
//                            double[] fMin = new double[nodes.Length];
//                            double[] fAngle = new double[nodes.Length];
//                            double[] fVM = new double[nodes.Length];
//                            results = new double[ro.Const("kMaxPlateResult")];

//                            if (ro.GetPlateResultArray(modelId, ro.Const("rtPlateForce"), ro.Const("stPlateCombined"), plateId, resultCase, average, plane, 0, ref numPoints, ref numColumns, ref results))
//                            {
//                                for (int i = 0; i < numPoints; i++)
//                                {
//                                    fMax[i] = results[i * numColumns + ro.Const("ipPlateCombPrincipal11")];
//                                    fMin[i] = results[i * numColumns + ro.Const("ipPlateCombPrincipal22")];
//                                    fAngle[i] = results[i * numColumns + ro.Const("ipPlateCombPrincipalAngle")];
//                                    fVM[i] = results[i * numColumns + ro.Const("ipPlateCombVonMises")];
//                                }

//                                //Setting results
//                                for (int i = 0; i < numPoints; i++)
//                                {
//                                    PlateForceResultModel result = new PlateForceResultModel(caseModel, nodes[i].ToString(), 0, "")
//                                    {
//                                        Force = f[i],
//                                        ForceMax = fMax[i],
//                                        ForceMin = fMin[i],
//                                        ForceAngle = fAngle[i],
//                                        ForceVonMises = fVM[i],
//                                        Moment = m[i],
//                                        MomentMax = mMax[i],
//                                        MomentMin = mMin[i],
//                                        MomentAngle = mAngle[i],
//                                        TransverseShearForce = shear[i],
//                                        TransverseShearForceMax = 0,
//                                        TransverseShearForceAng = 0
//                                    };
//                                    plate.Results.Add(result);
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }

//        protected override void AppendAdditionalComponentMenuItems(ToolStripDropDown menu)
//        {
//            base.AppendAdditionalComponentMenuItems(menu);
//            Menu_AppendSeparator(menu);
//            Menu_AppendItem(menu, "Reset", (s, e) => _model = new GH_Model());
//        }

//        public override bool Write(GH_IWriter writer)
//        {
//            bool success = base.Write(writer);
//            if (!success)
//                return false;

//            _model.Write(writer);

//            return true;
//        }

//        public override bool Read(GH_IReader reader)
//        {
//            bool success = base.Read(reader);
//            if (!success)
//                return false;

//            _model.Read(reader);
//            _just_loaded = true;

//            return true;
//        }

//        protected override void BeforeSolveInstance()
//        {
//            base.BeforeSolveInstance();
//            if (_just_loaded)
//            {
//                if (!Params.Input[0].VolatileData.IsEmpty)
//                {
//                    GH_Model input_model = (GH_Model)Params.Input[0].VolatileData.get_Branch(0)[0];
//                    ModelHelper.RestoreModelGuids(input_model, ref _model);
//                    _just_loaded = false;
//                }
//            }
//        }

//        /// <summary>
//        /// Provides an Icon for the component.
//        /// </summary>
//        protected override System.Drawing.Bitmap Icon => Properties.Resources.StrausAnalysisIcon;

//        /// <summary>
//        /// Gets the unique ID for this component. Do not change this ID after release.
//        /// </summary>
//        public override Guid ComponentGuid => new Guid("1b7bb1d9-6b11-49fa-9c09-2ff4bc442aac");
//    }
//}
303 files24 directories