private static void SetFixturesInfo(ref XElement x_setup, string output_dir, SetupInfo setup_info, WorkPlaneOrigin model_origin,
                                            double fixture_tol)
        {
            if (setup_info.fixture_models != null)
            {
                if (setup_info.fixture_models.Count > 0)
                {
                    PowerMILLAutomation.SetExportTolerance(fixture_tol);
                    /* Export fixtures first */
                    setup_info.fixture_stl_fpaths = new List <string>();
                    foreach (string fixture_name in setup_info.fixture_models)
                    {
                        setup_info.fixture_stl_fpaths.Add(PowerMILLAutomation.ExportModel(fixture_name, output_dir));
                    }
                }
            }

            /* Set fixture data in the .xml file */
            if (setup_info.fixture_stl_fpaths != null)
            {
                if (setup_info.fixture_stl_fpaths.Count > 0)
                {
                    XElement target = x_setup.Descendants("Component").Where(e => e.Attribute("Name").Value.ToUpper() == "FIXTURE" && e.Attribute("Type") != null).First();

                    /* Remove fixture from new project*/
                    remove_components_from_xml(target.Elements(), Properties.Resources.IDS_RemoveFixture);

                    target.Element("Attach").Value = setup_info.fixture_attach_to;
                    foreach (string stl_fpath in setup_info.fixture_stl_fpaths)
                    {
                        if (String.IsNullOrEmpty(stl_fpath))
                        {
                            continue;
                        }
                        target.Add(new XElement("STL",
                                                new XAttribute("Unit", (ProjectData.PmillUnitsIsInch ? "inch" : "Millimeter")),
                                                new XAttribute("Normal", "Computed"),
                                                new XAttribute("Visible", "on"),
                                                new XAttribute("XRGB", "0x00A0A0A0"),
                                                new XAttribute("Mirror", "off"),
                                                new XAttribute("MirrorCsys", "0"),
                                                //new XAttribute("Hue", 1),
                                                new XElement("Position",
                                                             new XAttribute("X", model_origin.dX),
                                                             new XAttribute("Y", model_origin.dY),
                                                             new XAttribute("Z", model_origin.dZ)),
                                                new XElement("Rotation",
                                                             new XAttribute("I", model_origin.dXangle),
                                                             new XAttribute("J", model_origin.dYangle),
                                                             new XAttribute("K", model_origin.dZangle)),
                                                new XElement("File", stl_fpath)
                                                ));
                    }
                }
            }
        }
        private static void SetBlockInfo(ref XElement x_setup, string output_dir, SetupInfo setup_info, WorkPlaneOrigin model_origin,
                                         double block_tol)
        {
            /* Depending on what's selected in UI, export block associated with toolpath or a stock model */
            if (!String.IsNullOrEmpty(setup_info.block_toolpath))
            {
                PowerMILLAutomation.SetExportTolerance(block_tol);
                setup_info.block_stl_fpath = PowerMILLAutomation.ExportBlock(setup_info.block_toolpath, output_dir);
            }
            if (!String.IsNullOrEmpty(setup_info.block_stockmodel))
            {
                PowerMILLAutomation.SetExportTolerance(block_tol);
                setup_info.block_stl_fpath = PowerMILLAutomation.ExportStockModel(setup_info.block_stockmodel, output_dir);
            }

            /* Set block data in the .xml file */
            if (!String.IsNullOrEmpty(setup_info.block_stl_fpath))
            {
                XElement target = x_setup.Descendants("Component").Where(e => e.Attribute("Name").Value.ToUpper() == "STOCK" && e.Attribute("Type") != null).First();

                /* Remove template stock from new project */
                remove_components_from_xml(target.Elements(), "The template file may contain a stock, would you like to remove it from the output project?");

                target.Element("Attach").Value = setup_info.block_attach_to;

                target.Add(new XElement("STL",
                                        new XAttribute("Unit", (ProjectData.PmillUnitsIsInch ? "inch" : "Millimeter")),
                                        new XAttribute("Normal", "outward"),
                                        new XAttribute("Visible", "on"),
                                        new XAttribute("XRGB", "0x000000CC"),
                                        new XAttribute("Mirror", "off"),
                                        new XAttribute("MirrorCsys", "0"),
                                        //new XAttribute("Hue", 1),
                                        new XElement("Position",
                                                     new XAttribute("X", model_origin.dX),
                                                     new XAttribute("Y", model_origin.dY),
                                                     new XAttribute("Z", model_origin.dZ)),
                                        new XElement("Rotation",
                                                     new XAttribute("I", model_origin.dXangle),
                                                     new XAttribute("J", model_origin.dYangle),
                                                     new XAttribute("K", model_origin.dZangle)),
                                        new XElement("File", setup_info.block_stl_fpath)
                                        ));
            }
        }
        /// <summary>
        /// Create the NXF File
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        private static bool GetListOfTools(SetupInfo setup_info, PluginSettings plugin_settings, string output_dir, out PowerMILLExporter.Tools.Tools setup_tools)
        {
            List <PowerMILLExporter.Tools.NCProgramTool> oTools = new List <PowerMILLExporter.Tools.NCProgramTool>();
            int        iInitToolNum     = -1;
            bool       bReturn          = true;
            List <int> oUsedToolNumbers = new List <int>();

            PowerMILLAutomation.ExecuteEx(String.Format(System.Globalization.CultureInfo.InvariantCulture,
                                                        "$Powermill.Export.TriangleTolerance = \"{0}\"", plugin_settings.export_options.tool_tol));

            setup_tools = new PowerMILLExporter.Tools.Tools();
            // For each NC prog, create and add tools in list of tools
            for (int nc_i = 0; nc_i < setup_info.nc_progs.Count; nc_i++)
            {
                if (String.IsNullOrEmpty(setup_info.nc_progs[nc_i].sName))
                {
                    continue;
                }
                EventLogger.WriteToEvengLog("Get all toolpaths for nc program " + setup_info.nc_progs[nc_i].sName);

                setup_info.toolpaths = PowerMILLAutomation.GetNCProgToolpathes(setup_info.nc_progs[nc_i].sName);
                EventLogger.WriteToEvengLog("Get all tools for nc program " + setup_info.nc_progs[nc_i].sName);

                //OTools get's out of the function with the first toolpath missing
                MainModule.FillNCProgramTools(setup_info.nc_progs[nc_i].sName, setup_info.toolpaths, nc_i, out oTools, ref iInitToolNum);

                setup_info.nc_progs[nc_i].oTools = oTools;


                EventLogger.WriteToEvengLog("Get tool info for nc program " + setup_info.nc_progs[nc_i].sName);

                bReturn &= WriteTools.CreateListOfTools(setup_info.toolpaths, output_dir, setup_info.nc_progs, ref oUsedToolNumbers, ref setup_tools);
            }

            return(bReturn);
        }
        public static void SetCSysInfo(ref XElement x_setup, SetupInfo setup_info, string cut_stock_csys)
        {
            IEnumerable <XElement> rows = x_setup.Descendants("CSystem");
            XElement lastrow;

            if (rows.Count() == 0)
            {
                IEnumerable <XElement> csystems = x_setup.Descendants("CSystems");
                if (csystems.Count() == 0)
                {
                    x_setup.Add(
                        new XElement("CSystems"),
                        new XAttribute("Simulation", "off"),
                        new XElement("Machine")
                        );
                    csystems = x_setup.Descendants("CSystems");
                }
                csystems.Last().Add(
                    new XElement("CSystem",
                                 new XAttribute("Name", "Global"),
                                 new XAttribute("Type", "component"),
                                 new XAttribute("Visible", "all"),
                                 new XElement("Attach", "Attach"),
                                 new XElement("Position",
                                              new XAttribute("X", 0),
                                              new XAttribute("Y", 0),
                                              new XAttribute("Z", 0)),
                                 new XElement("Rotation",
                                              new XAttribute("I", 0),
                                              new XAttribute("J", 0),
                                              new XAttribute("K", 0))
                                 ));
                rows = x_setup.Descendants("CSystem");
            }
            lastrow = rows.Last();
            lastrow.AddAfterSelf(
                new XElement("CSystem",
                             new XAttribute("Name", setup_info.attach_workplane),
                             new XAttribute("Type", "component"),
                             new XAttribute("Visible", "all"),
                             new XElement("Attach", "Attach"),
                             new XElement("Position",
                                          new XAttribute("X", 0),
                                          new XAttribute("Y", 0),
                                          new XAttribute("Z", 0)),
                             new XElement("Rotation",
                                          new XAttribute("I", 0),
                                          new XAttribute("J", 0),
                                          new XAttribute("K", 0))
                             ));
            PowerMILLAutomation.ActivateWorkplane(setup_info.attach_workplane);
            foreach (string wp in setup_info.workplanes_to_export)
            {
                if (wp == setup_info.attach_workplane)
                {
                    continue;
                }
                WorkPlaneOrigin orig = MainModule.GetWorkplaneCoords(PowerMILLAutomation.oToken, wp, true, Properties.Resources.IDS_WorkplaneFailedToGet);
                lastrow.AddAfterSelf(
                    new XElement("CSystem",
                                 new XAttribute("Name", wp),
                                 new XAttribute("Type", "component"),
                                 new XAttribute("Visible", "all"),
                                 new XAttribute("Transition", (wp.Equals(cut_stock_csys, StringComparison.OrdinalIgnoreCase) ? "on" : "off")),
                                 new XElement("Attach", (!wp.Equals(cut_stock_csys) ? setup_info.attach_workplane_to : setup_info.block_attach_to)),
                                 new XElement("Position",
                                              new XAttribute("X", orig.dX),
                                              new XAttribute("Y", orig.dY),
                                              new XAttribute("Z", orig.dZ)),
                                 new XElement("Rotation",
                                              new XAttribute("I", orig.dXangle),
                                              new XAttribute("J", orig.dYangle),
                                              new XAttribute("K", orig.dZangle))
                                 ));
            }
        }
        /// <summary>
        /// Create the different Output Files
        /// </summary>
        /// <remarks>nxf File,stl, iso, ...</remarks>
        public static string CreateOutputFiles(ProjectData proj_data, string output_dir, PluginSettings plugin_settings)
        {
            string project_fpath = Path.Combine(output_dir, ProjectData.ProjectName + ".vcproject");

            XDocument main_doc;

            try
            {
                main_doc = XDocument.Load(proj_data.proj_template);
            }
            catch
            {
                Messages.ShowError(Properties.Resources.IDS_VericutTemplateReadFailure, proj_data.proj_template);
                return("*");
            }

            main_doc.Descendants("Setup").Remove();
            if (main_doc.Descendants("InfoUserName").Count() > 0)
            {
                main_doc.Descendants("InfoUserName").First().Value =
                    String.Format("PowerMill to Vericut plugin v{0}.{1}.{2}",
                                  System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Major,
                                  System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Minor,
                                  System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Build);
            }

            for (int i = 0; i < proj_data.setup_infos.Count; i++)
            {
                XDocument doc;
                XElement  setup;
                SetupInfo setup_info = proj_data.setup_infos[i];

                PowerMILLAutomation.CreateTransformWorkplane("Transform_Vericut");
                PowerMILLAutomation.ActivateWorkplane(setup_info.attach_workplane);
                //WorkPlaneOrigin model_origin = MainModule.GetWorkplaneCoords(PowerMILLAutomation.oToken, setup_info.model_workplane, false, Properties.Resources.IDS_WorkplaneFailedToGet);
                WorkPlaneOrigin model_origin = MainModule.GetWorkplaneCoords(PowerMILLAutomation.oToken, "Transform_Vericut", true, Properties.Resources.IDS_WorkplaneFailedToGet);//Changed relation to true and look for the Transform position from the model location to align correctly in Vericut
                PowerMILLAutomation.DeleteTransformWorkplane("Transform_Vericut");


                string template = null;
                if (String.IsNullOrEmpty(setup_info.template) || !File.Exists(setup_info.template))
                {
                    template = proj_data.proj_template;
                }
                else
                {
                    template = setup_info.template;
                }
                doc = XDocument.Load(template);

                // Add path to items from the template
                IEnumerable <XElement> rows = doc.Descendants("File");
                foreach (XElement file in rows.ToList())
                {
                    string file_name = (file.FirstNode != null) ? file.FirstNode.ToString() : null;
                    if (!String.IsNullOrEmpty(file_name) && !String.IsNullOrEmpty(Path.GetExtension(file_name)) &&
                        String.IsNullOrEmpty(Path.GetDirectoryName(file_name)))
                    {
                        string full_path   = Path.Combine(Path.GetDirectoryName(template), file_name);
                        string new_element = file.ToString().Replace(file_name, full_path);

                        file.ReplaceWith(XElement.Parse(new_element));
                    }
                }

                setup = doc.Descendants("Setup").First();
                setup.Attribute("Name").Value = setup_info.name;

                PowerMILLExporter.Tools.Tools setup_tools;
                GetListOfTools(setup_info, plugin_settings, proj_data.output_dir, out setup_tools);
                setup_info.oTools = setup_tools;

                if (setup_info.tools_to_use == 0)
                {
                    EventLogger.WriteToEvengLog("Write tool info to tools.xml");
                    WriteTools.WriteToolsToXML(setup_info.oTools, output_dir, setup_info.name + "_tools.tls", plugin_settings.tool_id_use_num, plugin_settings.tool_id_use_name);

                    //output_dir, setup_info.name + "_tools.tls"
                    SetTools(ref setup, Path.Combine(output_dir, setup_info.name + "_tools.tls"));
                }
                else
                {
                    List <string> lib_tools     = GetListOfToolsFromLibrary(setup_info.tls_fpath);
                    List <string> missing_tools = WriteTools.FindToolsMissingFromLibrary(setup_info.oTools, lib_tools);
                    if (missing_tools.Count > 0)
                    {
                        if (setup_info.tools_to_use == 1)
                        {
                            Messages.ShowWarning(String.Format("Setup {0}: the following tools are missing from the library:\r\n {1}.", setup_info.name, String.Join(Environment.NewLine, missing_tools.ToArray())));
                        }
                        else if (setup_info.tools_to_use == 2)
                        {
                            EventLogger.WriteToEvengLog("Write tool info to tools.xml");
                            WriteTools.AppendToolsToXML(setup_info.oTools, output_dir, setup_info.tls_fpath, missing_tools);

                            //output_dir, setup_info.name + "_tools.tls"
                            SetTools(ref setup, Path.Combine(output_dir, setup_info.tls_fpath));
                        }
                    }
                }

                SetWorkOffsets(ref setup, setup_info);

                if (setup_info.tools_to_use == 1 || setup_info.tools_to_use == 2)
                {
                    SetNCPrograms(ref setup, setup_info, false, true);
                }
                else
                {
                    SetNCPrograms(ref setup, setup_info, plugin_settings.tool_id_use_num, plugin_settings.tool_id_use_name);
                }

                SetCSysInfo(ref setup, setup_info, proj_data.cut_stock_csys);

                /* Don't set block info for 2nd and other setups if using cut stock transition */
                if (i == 0 || String.IsNullOrEmpty(proj_data.cut_stock_csys))
                {
                    SetBlockInfo(ref setup, output_dir, setup_info, model_origin, plugin_settings.export_options.block_tol);
                }

                SetFixturesInfo(ref setup, output_dir, setup_info, model_origin, plugin_settings.export_options.fixture_tol);

                /* Don't set part info for 2nd and other setups if using cut stock transition */
                if (i == 0 || String.IsNullOrEmpty(proj_data.cut_stock_csys))
                {
                    SetPartsInfo(ref setup, output_dir, setup_info, model_origin, plugin_settings.export_options.model_tol);
                }

                if (i == 0)
                {
                    main_doc.Elements("VcProject").First().Add(setup);
                }
                else
                {
                    if (main_doc.Descendants("Setup").Count() > 0)
                    {
                        main_doc.Descendants("Setup").Last().AddAfterSelf(setup);
                    }
                }
            }

            main_doc.Save(project_fpath);


            return(project_fpath);
        }
        internal string VerifySetupInfo(string prefix, bool is_error)
        {
            string warning_message = "";

            // Verify setup template and load components and subsystems.
            bool verify_components = true;

            if (!VerifyFile(ref template, ref warning_message, prefix))
            {
                warning_message  += prefix + String.Format(Properties.Resources.IDS_NoTemplateVerification) + "\n";
                verify_components = false;
                template          = "";
            }
            if (String.IsNullOrWhiteSpace(template))
            {
                verify_components = false;
            }
            if (verify_components)
            {
                setup_attach_components = FindAllAttachComponents(System.IO.Path.GetFullPath(template));
                setup_attach_components.Sort();
                setup_subsystems = VericutMachineReader.GetMachineSubsystems(System.IO.Path.GetFullPath(template));
                setup_subsystems.Sort();
            }

            pmtoolpaths  = PowerMILLAutomation.GetListOf(PowerMILLAutomation.enumEntity.Toolpaths);
            nc_programs  = PowerMILLAutomation.GetListOf(PowerMILLAutomation.enumEntity.NCPrograms);
            models       = PowerMILLAutomation.GetListOf(PowerMILLAutomation.enumEntity.Models);
            stock_models = PowerMILLAutomation.GetListOf(PowerMILLAutomation.enumEntity.StockModels);

            VerifyWorkplane(ref attach_workplane, ref warning_message, prefix);
            if (verify_components)
            {
                VerifyComponent(ref attach_workplane_to, ref warning_message, prefix);
            }

            if (verify_components)
            {
                VerifyComponent(ref block_attach_to, ref warning_message, prefix);
            }
            if (is_error)
            {
                VerifyFile(ref block_stl_fpath, ref warning_message, prefix);
            }

            VerifyStockModel(ref block_stockmodel, ref warning_message, prefix);
            if (is_error)
            {
                VerifyFile(ref block_toolpath, ref warning_message, prefix);
            }

            if (verify_components)
            {
                VerifyComponent(ref fixture_attach_to, ref warning_message, prefix);
            }

            VerifyModels(fixture_models, ref warning_message, prefix);
            if (is_error)
            {
                VerifyFiles(fixture_stl_fpaths, ref warning_message, prefix);
            }

            VerifyWorkplane(ref model_workplane, ref warning_message, prefix);

            VerifyNCPrograms(nc_progs, ref warning_message, prefix);
            VerifyWorkplane(ref nc_workplane, ref warning_message, prefix);

            if (verify_components)
            {
                VerifyWorkOffsets(offsets, ref warning_message, prefix);
            }

            if (verify_components)
            {
                VerifyComponent(ref part_attach_to, ref warning_message, prefix);
            }
            VerifyModels(part_models, ref warning_message, prefix);
            if (is_error)
            {
                VerifyFiles(part_stl_fpaths, ref warning_message, prefix);
                VerifyFile(ref tls_fpath, ref warning_message, prefix);
            }

            VerifyToolpaths(toolpaths, ref warning_message, prefix);
            VerifyWorkplanes(workplanes_to_export, ref warning_message, prefix);

            return(warning_message);
        }