static public void ListFeatureTypes()
        {
            FMDocument doc   = (FMDocument)Application.ActiveDocument;
            string     fList = "";

            foreach (FMFeature feature in doc.Features)
            {
                tagFMFeatureType type;
                feature.GetFeatureType(out type);
                fList += $"{feature.Name} {type} \n";
            }
            mBox.Show(fList);
        }
        private static void SaveNCForSetup(FMDocument doc, FMSetup setup,
                                           string fname_no_ext, string ext, string output_dirpath,
                                           out int nc_files_num, out object nc_file_names,
                                           out string err_msg, ref bool is_op_error)
        {
            int    doc_files_num, macro_files_num;
            object doc_file_names, macro_file_names;


            nc_files_num  = 0;
            err_msg       = "";
            nc_file_names = null;

            LogFile.Write(String.Format("Run sim and save nc for setup {0}", setup.Name));
            setup.Activate();
            doc.SimToolpath(false);

            is_op_error = false;
            foreach (FeatureCAM.FMFeature feat in setup.Features)
            {
                for (int i = 1; i <= feat.Operations.Count; i++)
                {
                    if (feat.Operations.Item(i).Errors.Trim() != "")
                    {
                        is_op_error = true;
                    }
                }
            }

            if (is_op_error)
            {
                LogFile.Write("There are errors in the setup's operations list. NC code will not be exported. Project file won't be exported as well.");
                return;
            }

            doc.SaveNC(fname_no_ext + ext, output_dirpath, true,
                       FeatureCAM.tagFMSaveNCFileType.eNCFT_NCCode, false, out err_msg,
                       out nc_files_num, out nc_file_names, out doc_files_num, out doc_file_names,
                       out macro_files_num, out macro_file_names);
            LogFile.Write(String.Format("{0} file(s) created", nc_files_num));
        }
        public static void ToolsToList(FeatureCAM.Application app, FMDocument doc,
                                       List <SetupInfo> setups_info, List <bool> save_tools_for_all_setups,
                                       bool is_single_program, string output_dir, bool is_doc_metric)
        {
            List <string> setup_tools = new List <string>();
            //string unsupported_tool_names;
            string            tool_name;
            FMTool            tool;
            FMToolMap2        toolmap;
            tagFMTurretIDType turret_id;
            bool temp;


            for (int i = 1; i <= doc.Setups.Count; i++)
            {
                if (doc.Setups.Item(i).Enabled)
                {
                    doc.Setups.Item(i).Activate();
                    if (!is_single_program)
                    {
                        if (save_tools_for_all_setups[i - 1])
                        {
                            setup_tools.Add(GetToolsInSetups(doc.Setups.Item(i)));
                        }
                        else
                        {
                            setup_tools.Add("");
                        }
                    }
                    else
                    {
                        setup_tools.Add(GetToolsInSetups(doc.Setups.Item(i)));
                    }
                }
            }

            /* If we need to create separate tls file for each setup, write tools for each setup to a separate file */
            doc.InvalidateToolpaths();
            if (!is_single_program)
            {
                for (int si = 1; si <= doc.Setups.Count && doc.Setups.Item(si).Enabled; si++)
                {
                    ((FMSetup)doc.Setups.Item(si)).Activate(); //Need this line for A-038162 VERICUT: If option Combine setups isn't turned on and exporting 2 milling setups, we get tool export error.
                    if (save_tools_for_all_setups[si - 1])
                    {
                        LogFile.Write(String.Format("Construct tool list for setup {0}", doc.Setups.Item(si).Name));
                        for (int i = 1; i <= doc.ToolMaps.Count; i++)
                        {
                            toolmap = doc.ToolMaps.Item(i);
                            if (toolmap.Operations.Count > 0)
                            {
                                tool       = (FMTool)toolmap.Tool;
                                tool_name  = "";
                                tool_name += tool.Name;
                                if (setup_tools[si - 1].IndexOf(tool_name) >= 0)
                                {
                                    app.GetTurnTurretInfo(toolmap.turret, out temp, out turret_id, out temp, out temp, out temp, out temp);
                                    FeatureCAMTool fc_tool = new FeatureCAMTool(toolmap, tool, turret_id, app.TurningInputMode, output_dir, is_doc_metric);
                                    if (setups_info[si - 1].tools == null)
                                    {
                                        setups_info[si - 1].tools = new List <FeatureCAMTool>();
                                    }
                                    setups_info[si - 1].tools.Add(fc_tool);
                                }
                            }
                        }
                    }
                    else
                    {
                        LogFile.Write(String.Format("Skip setup {0}. User chose not to export tools for it", doc.Setups.Item(si).Name));
                    }
                }
            }
            else
            {
                string all_tools;
                all_tools = String.Join(";", setup_tools);

                bool save_tools = true;
                foreach (bool save_tools_for_setup in save_tools_for_all_setups)
                {
                    save_tools &= save_tools_for_setup;
                }
                if (save_tools)
                {
                    LogFile.Write("Construct tool list for all features in the part");
                    for (int i = 1; i <= doc.ToolMaps.Count; i++)
                    {
                        toolmap = doc.ToolMaps.Item(i);
                        /* Doing below check, because toolmap.Operations.Count didn't seem to work every time */
                        if (all_tools.Contains(toolmap.Tool.Name + ";"))
                        {
                            tool = (FMTool)toolmap.Tool;
                            app.GetTurnTurretInfo(toolmap.turret, out temp, out turret_id, out temp, out temp, out temp, out temp);
                            FeatureCAMTool fc_tool = new FeatureCAMTool(toolmap, tool, turret_id, app.TurningInputMode, output_dir, is_doc_metric);
                            if (setups_info[0].tools == null)
                            {
                                setups_info[0].tools = new List <FeatureCAMTool>();
                            }
                            setups_info[0].tools.Add(fc_tool);
                        }
                    }
                }
            }
        }
        private static void ExportTools(FeatureCAM.Application app, FMDocument doc)
        {
            StringBuilder tool_info    = new StringBuilder(),
                          tls_fcontent = new StringBuilder(),
                          tool_list    = new StringBuilder();
            int nc_prog          = 1,
                init_num         = 1;
            string crib_pos      = "",
                   nc_prog_fpath = "";

            try
            {
                /* At the moment we construct full tool list, which can be time consuming.
                 * So if we have a lot of setups that don't get exported, we do have a pointless delay
                 */
                FCExporter.ToolsToList(app, doc, Variables.setups_info, Variables.GetSaveToolsForAllSetups(),
                                       (Variables.doc_options.combine_setups == 1), Variables.doc_options.output_dirpath, Variables.doc.Metric);
                if (Variables.doc_options.combine_setups == 0)
                {
                    for (int si = 0; si < Variables.setups_info.Count; si++)
                    {
                        if (Variables.setups_info[si].options.is_export_tools)
                        {
                            Variables.setups_info[si].tool_fpath = Path.Combine(Variables.doc_options.output_dirpath,
                                                                                Variables.fname_no_ext + "_" + (string)Variables.setups_info[si].name + ".tls");
                            tool_info    = new StringBuilder();
                            tls_fcontent = new StringBuilder();
                            tool_list    = new StringBuilder();
                            for (int i = 0; i < Variables.setups_info[si].tools.Count; i++)
                            {
                                if (Variables.setups_info[si].tools[i].cutter_geom.Count == 0)
                                {
                                    continue;
                                }
                                if (tool_info.Length > 0)
                                {
                                    tool_info.AppendLine("");
                                }
                                tool_info.Append(
                                    VericutTool.ToXML(Variables.setups_info[si].tools[i], doc.Metric));
                                nc_prog       = Convert.ToInt32(Convert.ToString(Variables.setups_info[si].tools[i].turr_type).Replace("eTT_TURRET", ""));
                                nc_prog_fpath = Variables.setups_info[si].nc_fpaths[nc_prog - 1];
                                crib_pos      = String.Format("{0}:{1}",
                                                              Convert.ToString(Variables.setups_info[si].tools[i].turr_type).Replace("eTT_TURRET", ""),
                                                              Convert.ToInt32(Variables.setups_info[si].tools[i].id));
                                AppendToToolList(tool_list, nc_prog, init_num, crib_pos, nc_prog_fpath, Variables.setups_info[si].tools[i].optional_id);
                            }
                            Variables.setups_info[si].tool_list = "<ToolChange>" + Environment.NewLine +
                                                                  Utilities.Indent(tool_list.ToString(), 1) +
                                                                  "</ToolChange>";
                            tls_fcontent.AppendLine("<?xml version=\"1.0\"?>");
                            tls_fcontent.AppendLine("<CGTechToolLibrary>");
                            tls_fcontent.AppendLine(Utilities.Indent("<Tools>", 1));
                            tls_fcontent.AppendLine(Utilities.Indent(tool_info.ToString(), 2));
                            tls_fcontent.AppendLine(Utilities.Indent("</Tools>", 1));
                            tls_fcontent.Append("</CGTechToolLibrary>");
                            File.WriteAllText(Variables.setups_info[si].tool_fpath, tls_fcontent.ToString());
                            LogFile.Write(String.Format("Tool info was written to {0}", Variables.setups_info[si].tool_fpath));
                        }
                    }
                }
                else
                {
                    if (Variables.setups_info[0].options.is_export_tools)
                    {
                        for (int si = 0; si < Variables.setups_info.Count; si++)
                        {
                            if (Variables.setups_info[si].options.is_export_tools)
                            {
                                Variables.setups_info[si].tool_fpath = Path.Combine(Variables.doc_options.output_dirpath,
                                                                                    Variables.fname_no_ext + ".tls");
                            }
                        }
                        for (int i = 0; i < Variables.setups_info[0].tools.Count; i++)
                        {
                            if (Variables.setups_info[0].tools[i].cutter_geom.Count == 0)
                            {
                                continue;
                            }
                            tool_info.Append(tool_info.Length > 0 ? "\n" : "");
                            tool_info.Append(
                                VericutTool.ToXML(Variables.setups_info[0].tools[i], Variables.doc.Metric));
                            nc_prog       = Convert.ToInt32(Convert.ToString(Variables.setups_info[0].tools[i].turr_type).Replace("eTT_TURRET", ""));
                            nc_prog_fpath = Variables.setups_info[0].nc_fpaths[nc_prog - 1];
                            crib_pos      = String.Format("{0}:{1}",
                                                          Convert.ToString(Variables.setups_info[0].tools[i].turr_type).Replace("eTT_TURRET", ""),
                                                          Convert.ToInt32(Variables.setups_info[0].tools[i].id));
                            AppendToToolList(tool_list, nc_prog, init_num, crib_pos, nc_prog_fpath, Variables.setups_info[0].tools[i].optional_id);
                        }
                        Variables.setups_info[0].tool_list = "<ToolChange>" + Environment.NewLine +
                                                             Utilities.Indent(tool_list.ToString(), 1) +
                                                             "</ToolChange>";
                        tls_fcontent.AppendLine("<?xml version=\"1.0\"?>");
                        tls_fcontent.AppendLine("<CGTechToolLibrary>");
                        tls_fcontent.AppendLine(Utilities.Indent("<Tools>", 1));
                        tls_fcontent.AppendLine(Utilities.Indent(tool_info.ToString(), 2));
                        tls_fcontent.AppendLine(Utilities.Indent("</Tools>", 1));
                        tls_fcontent.Append("</CGTechToolLibrary>");
                        File.WriteAllText(Variables.setups_info[0].tool_fpath, tls_fcontent.ToString());
                        LogFile.Write(String.Format("Tool info was written to {0}", Variables.setups_info[0].tool_fpath));
                    }
                }
            }
            catch (Exception Ex)
            {
                LogFile.Write(String.Format("Exception occured during tool export. Exception details: {0}\n", Ex.Message));
                MessageDisplay.ShowError(
                    LanguageSupport.Translate("Failed to export tools"));
            }
        }