明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 587|回复: 2

[【IFoxCAD】] 命令:封閉空間等分

[复制链接]
发表于 2024-2-18 05:08 | 显示全部楼层 |阅读模式
本帖最后由 箭头_Row 于 2024-2-18 05:36 编辑

命令描述:關於選擇封閉空間后等分命令。

命令步驟:
步驟一:選擇封閉。
步驟二:選擇分割分式。

備註:下述代碼使用了IFox庫。

源碼如下:
  1. namespace ArrowTools;
  2. public class DivisionEX : SettingsClass
  3. {
  4.     public enum FirstKeywords
  5.     {
  6.         [Description("S")]
  7.         选取 = 1,
  8.         [Desic virtual string JsonFile() => Path.GetDirectoryName(GetAssemblyPath(true)) + "\\Settings\\";
  9.     public virtual string JsonFile() => Path.GetDirectoryName(ArrowTool.GetAssemblyPath(true)) + $"\\Settings\\{this.GetType().Name}_Settings.json";
  10.     public virtual string JsonString() => JsonConvert.SerializeObject(this, Formatting.Indented);
  11.     public virtual void JsonSaveAs() => File.WriteAllText(JsonFile(), JsonString());
  12.     pubcription("R")]
  13.         两点 = 2,
  14.     }
  15.     public enum Keywords
  16.     {
  17.         [Description("V")]
  18.         垂直 = 1,
  19.         [Description("H")]
  20.         水平 = 2,
  21.         [Description("C")]
  22.         图层 = 4,
  23.         [Description("N")]
  24.         数量 = 16,
  25.         [Description("J")]
  26.         定距 = 8,
  27.         [Description("S")]
  28.         定数,
  29.         [Description("T")]
  30.         板厚 = 64,
  31.         [Description("D")]
  32.         距离,
  33.         [Description("Z")]
  34.         中心 = 32,
  35.         [Description("A")]
  36.         中有分点,
  37.         [Description("X")]
  38.         双线,
  39.         [Description("+")]
  40.         加,
  41.         [Description("-")]
  42.         减,
  43.         [Description("1")]
  44.         加1,
  45.         [Description("2")]
  46.         减1,
  47.         [Description("W")]
  48.         加一,
  49.         [Description("E")]
  50.         减一
  51.     }

  52.     public override string ToString() => JsonString();
  53.     public void PrintKeywordsSettings() =>
  54.         Env.Print($"\n图层:{DivEXLayer}  备注:定数模式下 “1”、“2”、“+”、“-”、“W”、“E” 可加减分段数!" +
  55.                   $"\n分割:{DivStyle.GetEnumByDescription<Keywords>()}  双线:{(isDoubleLine ? "是" : "否")}  距离:{distension}  数量:{number}  " +
  56.                   $"\n垂线:{(VerticalDivStyle ? "垂直" : "水平")}  中心:{(isCenterDivision ? "是" : "否")}  中心有线:{(centerHasLine ? "是" : "否")}  板厚:{thickness}  ");
  57.     private static string GetEntityOptionsMessage()
  58.     {
  59.         return "\n点取闭合空间或 [选取(S)/两点(R)] ";
  60.     }
  61.     private string GetOptionsMessage(Line line)
  62.     {
  63.         string msg;
  64.         if (DivStyle == Keywords.定数.GetDesc() && isDoubleLine)
  65.             msg = $"计算结果: \n{DivStyle.GetEnumByDescription<Keywords>()}({Keywords.定数.GetDesc()}) = {Math.Round((line.Length - thickness * (number - 1)) / number, 2)}  \n数量({Keywords.数量.GetDesc()}) = {number}  ({Keywords.加一.GetDesc()}/{Keywords.减一.GetDesc()})\n双线({Keywords.双线.GetDesc()}) = {(isDoubleLine ? "是" : "否")}  \n板厚({Keywords.板厚.GetDesc()}) = {thickness}";
  66.         else if (DivStyle == Keywords.定数.GetDesc() && !isDoubleLine)
  67.             msg = $"计算结果: \n{DivStyle.GetEnumByDescription<Keywords>()}({Keywords.定数.GetDesc()}) = {Math.Round(line.Length / number, 2)}  \n数量({Keywords.数量.GetDesc()}) = {number}  ({Keywords.加一.GetDesc()}/{Keywords.减一.GetDesc()})\n双线({Keywords.双线.GetDesc()}) = {(isDoubleLine ? "是" : "否")}  ";
  68.         else if (DivStyle == Keywords.定距.GetDesc() && isDoubleLine)
  69.             msg = $"计算结果: \n{DivStyle.GetEnumByDescription<Keywords>()}({Keywords.定数.GetDesc()}) = {distension}  {Keywords.距离}({Keywords.距离.GetDesc()})  \n数量(!) = {Math.Floor(line.Length / (distension + thickness))}  \n双线({Keywords.双线.GetDesc()}) = {(isDoubleLine ? "是" : "否")}  板厚({Keywords.板厚.GetDesc()}) = {thickness}  \n中心({Keywords.中心.GetDesc()}) = {(isCenterDivision ? "是" : "否")}  \n中心有线({Keywords.中有分点.GetDesc()}) = {(centerHasLine ? "是" : "否")}";
  70.         else
  71.             msg = $"计算结果: \n{DivStyle.GetEnumByDescription<Keywords>()}({Keywords.定数.GetDesc()}) = {distension}  {Keywords.距离}({Keywords.距离.GetDesc()})  \n数量(!) = {Math.Floor(line.Length / distension)}  \n双线({Keywords.双线.GetDesc()}) = {(isDoubleLine ? "是" : "否")}  \n中心({Keywords.中心.GetDesc()}) = {(isCenterDivision ? "是" : "否")}  \n中心有线({Keywords.中有分点.GetDesc()}) = {(centerHasLine ? "是" : "否")}";

  72.         return msg;
  73.     }
  74.     public override void ResetLayer()
  75.     {
  76.         DivEXLayer = Layers.EL_30_Name;
  77.         divEXLayerColor = Layers.EL_30_Color;
  78.     }

  79.     // 2024-2-7  注意:未實例化的類中標識符 public 將序列化,pravite 不會序列化類;
  80.     // 分割方式:定數 or 垂直
  81.     public string DivStyle { get; set; } = Keywords.定数.GetDesc();
  82.     public bool VerticalDivStyle = false;
  83.     // 圖層默認設置
  84.     public string? DivEXLayer { get; set; }
  85.     public short divEXLayerColor;
  86.     // 2024-2-8:"字段"是直接访问的变量,效率更高,只get无set。
  87.     // 2024-2-8:直接賦值{ get; }=方式值是固定死的,必須使用委託方式寫才會每次都獲取新值。
  88.     static string DivEXHsLayer => HsLayer(HesiStatusBridge.PboCAD.GetLayerStatus(), "18Norm");
  89.     // 分割偏移 bool 設置
  90.     public bool isDoubleLine = true;
  91.     public bool isCenterDivision = true;
  92.     public bool centerHasLine = true;
  93.     // 分割偏移其它值設置
  94.     public int number = 4;
  95.     public double distension = 100;
  96.     public double thickness = 10;

  97.     [CommandMethod(nameof(CzE_Division_EX))]
  98.     public void CzE_Division_EX()
  99.     {
  100.         InitLayersSettings(this);
  101.         if (this.DivEXLayer == null)
  102.             return;

  103.         bool selectMode = false;
  104.         bool twoPointMode = false;
  105.         Polyline pline = new();

  106.         PromptPointOptions entOpts = new("");
  107.         List<string> myFirstKeywords = CzEnumEx.GetDescriptionList(typeof(FirstKeywords));
  108.         entOpts.AddKeywords(myFirstKeywords);
  109.         entOpts.AppendKeywordsToMessage = false;//不将关键字列表添加到提示信息中  
  110.         entOpts.Message = GetEntityOptionsMessage();
  111.         entOpts.AllowNone = true;

  112.         PromptPointResult ppr = Env.Editor.GetPoint(entOpts);
  113.         if (ppr.Status == PromptStatus.OK)
  114.         {
  115.             // 获取Boundary 注意TraceBoundary 中 deleteisland 的设置
  116.             using DBObjectCollection dbo = Env.Editor.TraceBoundary(ppr.Value, false);
  117.             if (dbo.Count != 1)
  118.             {
  119.                 Env.Print("\n闭合空间错误,调整后重试!");
  120.                 return;
  121.             }
  122.             pline = (Polyline)dbo[0];
  123.             if (pline.NumberOfVertices == 0)
  124.             {
  125.                 Env.Print("\n闭合空间错误,调整后重试!");
  126.                 return;
  127.             }
  128.         }

  129.         using DBTrans tr = new();
  130.         if (ppr.Status == PromptStatus.Keyword)
  131.         {
  132.             switch (ppr.StringResult.ToUpper().GetEnumByDescription<FirstKeywords>())
  133.             {
  134.                 case FirstKeywords.选取:
  135.                     selectMode = true;
  136.                     while (selectMode)
  137.                     {
  138.                         var templine = GetClosedPolyline(tr);
  139.                         if (templine == null)
  140.                             return;
  141.                         if (templine.NumberOfVertices > 2)
  142.                         {
  143.                             pline = templine;
  144.                             selectMode = false;
  145.                         }
  146.                     }
  147.                     break;
  148.                 case FirstKeywords.两点:
  149.                     var templine2 = tr.TwoPointDrawRectangle();
  150.                     if (templine2 == null) return;

  151.                     pline = templine2;
  152.                     twoPointMode = true;
  153.                     break;
  154.             }
  155.         }
  156.         if (ppr.Status == PromptStatus.Cancel)
  157.         {
  158.             Env.Print("\n命令取消!");
  159.             return;
  160.         }

  161.         // 记录正交状态,命令結束或取消時還原
  162.         bool ortho = Env.OrthoMode;
  163.         if (Env.OrthoMode)
  164.             Env.OrthoMode = false;

  165.         List<Line> lines = [];
  166.         // 创建瞬态容器
  167.         using JigExTransient jet = new();
  168.         // 亮显模式加到瞬态容器,即在图纸上显示
  169.         if (pline.NumberOfVertices > 0)
  170.         {
  171.             // 如果是选取模式,须打开实体可读模式,否则报可写错误
  172.             var color = pline.Color;
  173.             if (!pline.IsWriteEnabled)
  174.                 using (pline.ForWrite())
  175.                     pline.ColorIndex = 1;
  176.             else
  177.                 pline.ColorIndex = 1;
  178.             jet.Add(pline, Acgi.TransientDrawingMode.Highlight);
  179.             pline.Color = color;
  180.             // 两点绘制模式时,瞬态显示后删除两点绘制的矩形,
  181.             // 因为TwoPointDrawRectangle()内加了瞬态,不加入数据库会报可写错误。
  182.             if (twoPointMode)
  183.                 pline.Erase();
  184.         }

  185.         PrintKeywordsSettings();

  186.         JigPromptPointOptions? options = null;
  187.         using var jig = new JigEx((mousePtWorld, drawEntitys) => {
  188.             var tempVect = VerticalDivStyle ? Vector3d.YAxis.Ucs2Wcs() : Vector3d.XAxis.Ucs2Wcs();
  189.             lines = mousePtWorld.GetIntersectLine(tempVect, pline);

  190.             if (lines.Count != 1)
  191.                 return;
  192.             using Line line = lines[0];
  193.             lines = [];

  194.             List<Point3d> listPoints = [];
  195.             if (DivStyle == Keywords.定数.GetDesc())
  196.             {
  197.                 for (int i = 1; i < number; i++)
  198.                 {
  199.                     if (!isDoubleLine)
  200.                     {
  201.                         double myDis = line.Length / number;
  202.                         AddDivisionPoints(line, listPoints, myDis * i);
  203.                     }
  204.                     else
  205.                     {
  206.                         if (thickness * (number - 1) > line.Length)
  207.                         {
  208.                             Env.Print("\n板厚设置错误!配置重置请联系 QQ:119 110 1855!");
  209.                             return;
  210.                         }
  211.                         double myDis = (line.Length - thickness * (number - 1)) / number;

  212.                         AddDivisionPoints(line, listPoints, (myDis * i + thickness * (i - 1)));
  213.                         AddDivisionPoints(line, listPoints, (myDis * i + thickness * i));
  214.                     }
  215.                 }
  216.             }
  217.             else
  218.             {
  219.                 if (!isCenterDivision)
  220.                 {
  221.                     // 判断线的方向,在定距情况下很重要
  222.                     if (line.StartPoint.DistanceTo(mousePtWorld) > line.EndPoint.DistanceTo(mousePtWorld))
  223.                         line.ReverseCurve();

  224.                     if (!isDoubleLine)
  225.                     {
  226.                         if (distension > line.Length)
  227.                         {
  228.                             Env.Print("/n距离设置错误!");
  229.                             return;
  230.                         }

  231.                         for (int i = 1; i < line.Length / distension; i++)
  232.                             AddDivisionPoints(line, listPoints, (distension * i));
  233.                     }
  234.                     else
  235.                     {
  236.                         if (distension + thickness > line.Length)
  237.                         {
  238.                             Env.Print("/n距离设置错误!");
  239.                             return;
  240.                         }

  241.                         for (int i = 1; i < line.Length / (distension + thickness); i++)
  242.                         {
  243.                             AddDivisionPoints(line, listPoints, (distension * i + thickness * (i - 1)));
  244.                             AddDivisionPoints(line, listPoints, (distension * i + thickness * i));
  245.                         }
  246.                         // 添加最后一段如果分割距离大于定距但小于定距+板厚的情况
  247.                         if (line.Length % (distension + thickness) > distension)
  248.                             AddDivisionPoints(line, listPoints, (line.Length - (line.Length % (distension + thickness) - distension)));
  249.                     }
  250.                 }
  251.                 else
  252.                 {
  253.                     if (!isDoubleLine)
  254.                     {
  255.                         //// 2024-2-6:因設置后後續無法切換奇偶數,故取消自動判斷如何合理等分,等分數奇數 or 偶數。
  256.                         //if (line.Length % distension > distension / 2)
  257.                         //    centerHasLine = true;
  258.                         //else
  259.                         //    centerHasLine = false;

  260.                         if (distension > line.Length)
  261.                         {
  262.                             Env.Print("\n距离设置错误!配置重置请联系 QQ:119 110 1855!");
  263.                             return;
  264.                         }
  265.                         if (centerHasLine)
  266.                             for (int i = -(int)Math.Floor((line.Length / 2) / distension); i <= (int)Math.Floor((line.Length / 2) / distension); i++)
  267.                                 AddDivisionPoints(line, listPoints, (distension * i + line.Length / 2));
  268.                         else
  269.                             for (int i = -(int)Math.Floor((line.Length - distension) / 2 / distension); i <= (int)Math.Floor((line.Length - distension) / 2 / distension) + 1; i++)
  270.                                 AddDivisionPoints(line, listPoints, (distension * i + line.Length / 2 - distension / 2));
  271.                     }
  272.                     else
  273.                     {
  274.                         if (distension + thickness > line.Length)
  275.                         {
  276.                             Env.Print("\n距离设置错误!配置重置请联系 QQ:119 110 1855!");
  277.                             return;
  278.                         }
  279.                         if (centerHasLine)
  280.                         {
  281.                             for (int i = -(int)Math.Floor((line.Length / 2) / (distension + thickness)); i <= (int)Math.Floor((line.Length / 2) / (distension + thickness)); i++)
  282.                             {
  283.                                 AddDivisionPoints(line, listPoints, (distension * i + thickness * (i - 1) + line.Length / 2 + thickness / 2));
  284.                                 AddDivisionPoints(line, listPoints, (distension * i + thickness * i + line.Length / 2 + thickness / 2));
  285.                             }
  286.                         }
  287.                         else
  288.                         {
  289.                             for (int i = -(int)Math.Floor(((line.Length - distension) / 2) / (distension + thickness)) - 1; i <= (int)Math.Floor(((line.Length - distension) / 2) / (distension + thickness)); i++)
  290.                             {
  291.                                 AddDivisionPoints(line, listPoints, (distension * i + thickness * i + line.Length / 2 + distension / 2));
  292.                                 AddDivisionPoints(line, listPoints, (distension * i + thickness * (i + 1) + line.Length / 2 + distension / 2));
  293.                             }
  294.                             ////添加最后一段如果分割距离大于定距但小于定距 + 板厚的情况
  295.                             //if ((line.Length - distension) % (distension + thickness) > 0)
  296.                             //{
  297.                             //    AddDivisionPoints(line, listPoints, ((line.Length - distension) % (distension + thickness) / 2));
  298.                             //    AddDivisionPoints(line, listPoints, (line.Length - ((line.Length - distension) % (distension + thickness) / 2)));
  299.                             //}
  300.                         }
  301.                     }
  302.                 }
  303.             }

  304.             // 生成等分线
  305.             var vector = VerticalDivStyle ? Vector3d.XAxis.Ucs2Wcs() : Vector3d.YAxis.Ucs2Wcs();
  306.             foreach (var newPoint in listPoints)
  307.                 foreach (Line lineIst in newPoint.GetIntersectLine(vector, pline))
  308.                     lines.Add(lineIst);

  309.             if (lines.Count > 0)
  310.                 foreach (Line ent in lines)
  311.                 {
  312.                     if (DivEXLayer == "当前")
  313.                         ent.SetDatabaseDefaults();
  314.                     else
  315.                         ent.SetProperty(DivEXHsLayer, DivEXLayer, divEXLayerColor);

  316.                     drawEntitys.Enqueue(ent);   // 加入刷新队列
  317.                 }

  318.             options!.Message = GetOptionsMessage(line);
  319.         });

  320.         options = jig.SetOptions(ppr.Value, CursorType.EntitySelect, "\n选择点或 [竖直\\水平(V\\H)/图层(C)/定数\\定距(S\\J)/数量(N)/距离(D)/板厚(T)/中心(Z)/中心有线(A)/双线(X)] ");
  321.         options.AppendKeywordsToMessage = false;  //不将关键字列表添加到提示信息中
  322.         List<string> myKeywords = CzEnumEx.GetDescriptionList(typeof(Keywords));
  323.         options.AddKeywords(myKeywords);
  324.         options.UseBasePoint = false;

  325.         bool jigDragFlag = true;
  326.         while (jigDragFlag)
  327.         {
  328.             var pr = jig.Drag();
  329.             if (pr.Status == PromptStatus.Keyword)
  330.             {
  331.                 switch (pr.StringResult.ToUpper().GetEnumByDescription<Keywords>())
  332.                 {
  333.                     case Keywords.垂直 or Keywords.水平:
  334.                         VerticalDivStyle = !VerticalDivStyle;
  335.                         break;
  336.                     case Keywords.定数 or Keywords.定距:
  337.                         if (DivStyle == Keywords.定数.GetDesc())
  338.                             DivStyle = Keywords.定距.GetDesc();
  339.                         else
  340.                             DivStyle = Keywords.定数.GetDesc();
  341.                         break;
  342.                     case Keywords.图层:
  343.                         string? layerName = tr.GetEntityLayer();
  344.                         if (layerName != null)
  345.                             DivEXLayer = layerName;
  346.                         if (layerName == "重置")
  347.                             ResetLayer();  //重置圖層
  348.                         break;
  349.                     case Keywords.数量:
  350.                         PromptIntegerOptions pio = new("输入数量")
  351.                         {
  352.                             LowerLimit = 2,
  353.                             UpperLimit = 100,
  354.                             DefaultValue = number
  355.                         };
  356.                         PromptIntegerResult pir = Env.Editor.GetInteger(pio);
  357.                         if (pir.Status == PromptStatus.OK)
  358.                             number = pir.Value;
  359.                         else
  360.                             Env.Print("输入错误!");
  361.                         break;
  362.                     case Keywords.距离:
  363.                         PromptDistanceOptions pdo = new("\n选择距离");
  364.                         pdo.DefaultValue = distension;
  365.                         PromptDoubleResult pdr = Env.Editor.GetDistance(pdo);
  366.                         if (pdr.Status == PromptStatus.OK)
  367.                             distension = Math.Round(pdr.Value, 2);
  368.                         break;
  369.                     case Keywords.板厚:
  370.                         thickness = BoardOffset.GetBoardThickness("\n点选板厚(或手动输入):", thickness);
  371.                         break;
  372.                     case Keywords.中心:
  373.                         isCenterDivision = !isCenterDivision;
  374.                         break;
  375.                     case Keywords.中有分点:
  376.                         centerHasLine = !centerHasLine;
  377.                         break;
  378.                     case Keywords.双线:
  379.                         isDoubleLine = !isDoubleLine;
  380.                         break;
  381.                     case Keywords.加 or Keywords.加1 or Keywords.加一:
  382.                         number += 1;
  383.                         break;
  384.                     case Keywords.减 or Keywords.减1 or Keywords.减一:
  385.                         if (number > 2)
  386.                             number -= 1;
  387.                         break;
  388.                 }
  389.                 //序列化*类转字符串
  390.                 JsonSaveAs();
  391.                 PrintKeywordsSettings();
  392.             }
  393.             else if (pr.Status == PromptStatus.OK || pr.Status == PromptStatus.None)
  394.             {
  395.                 //剔除未生成Line,还是初始化状态的情况
  396.                 if (jig.Entitys.Length <= 0)
  397.                     Env.Editor.WriteMessage("\n点超出边界,调整后重试!");
  398.                 else
  399.                     foreach (var entity in jig.Entitys)
  400.                         if (entity is Line)
  401.                             tr.CurrentSpace.AddEntity(entity);

  402.                 // 還原正交状态 and 點樣式
  403.                 Env.OrthoMode = ortho;
  404.                 jigDragFlag = false;
  405.             }
  406.             else
  407.             {   // 還原正交状态 and 點樣式
  408.                 Env.OrthoMode = ortho;
  409.                 Env.Print("\n命令取消!");
  410.                 return;
  411.             }
  412.         }
  413.     }

  414.     /// </summary>
  415.     /// 给定的分割线(Line)在指定距离(double)上添加分割点(Point3d)
  416.     /// </summary>
  417.     /// <param name="divisionLine">要添加分割點的分割線</param>
  418.     /// <param name="divisionPoints">用於保存分割點的列表</param>
  419.     /// <param name="distension">分割點與起點之間的距離</param>
  420.     private static void AddDivisionPoints(Line divisionLine, List<Point3d> divisionPoints, double distension)
  421.     {
  422.         //获取距离起点 mydis 的多段线上的一个点
  423.         Point3d point = divisionLine.GetPointAtDist(distension);
  424.         //一阶导数  即切线向量
  425.         Vector3d curVector = divisionLine.GetFirstDerivative(point);
  426.         //获取切线方向的垂线向量的标准单位向量 (从切线得到法线)
  427.         Vector3d curPervector = curVector.GetPerpendicularVector().GetNormal();
  428.         //起始点+ 单位向量*距离 就是距离起始点 距离向量长度的 一个点
  429.         Point3d newPoint = point + curPervector * distension;

  430.         divisionPoints.Add(newPoint);
  431.     }
  432. }



另一個C#文件名:SettingsClass.cs
關於初始化設置!!!!
  1. namespace ArrowTools;
  2. public interface IInitSettins
  3. {
  4.     /// <summary>
  5.     /// json文件:带文件名及后缀。
  6.     /// </summary>
  7.     /// <returns>完整文件名路徑 + 名稱</returns>
  8.     public string JsonFile();
  9.     /// <summary>
  10.     /// 序列化類
  11.     /// </summary>
  12.     /// <returns>序列化string</returns>
  13.     public string JsonString();
  14.     /// <summary>
  15.     /// 保存序列化類至配置文件。
  16.     /// </summary>
  17.     public void JsonSaveAs();
  18.     /// <summary>
  19.     /// 反序列化類
  20.     /// </summary>
  21.     /// <typeparam name="T">類名</typeparam>
  22.     /// <returns>配置轉類</returns>
  23.     public T JsonToType<T>();
  24.     /// <summary>
  25.     /// 圖層重置
  26.     /// </summary>
  27.     public void ResetLayer();
  28. }
  29. public class SettingsClass : IInitSettins
  30. {
  31.     public virtual void ResetLayer()
  32.     {
  33.     }
  34.     //public virtual string JsonFile() => Path.GetDirectoryName(GetAssemblyPath(true)) + "\\Settings\\";
  35.     public virtual string JsonFile() => Path.GetDirectoryName(ArrowTool.GetAssemblyPath(true)) + $"\\Settings\\{this.GetType().Name}_Settings.json";
  36.     public virtual string JsonString() => JsonConvert.SerializeObject(this, Formatting.Indented);
  37.     public virtual void JsonSaveAs() => File.WriteAllText(JsonFile(), JsonString());
  38.     public T JsonToType<T>() => JsonConvert.DeserializeObject<T>(File.ReadAllText(JsonFile()))!;
  39. }


關於接口文件:SettingsTools.cs
  1. namespace ArrowTools;
  2. public static class SettingsTools
  3. {
  4.     /// <summary>
  5.     /// 初始化圖層配置:檢查配置路徑。
  6.     /// </summary>
  7.     public static void InitLayersSettings<T>(T thisType) where T : class, IInitSettins
  8.     {
  9.         var path = thisType.JsonFile();
  10.         string dirName = Path.GetDirectoryName(path)!; // 获取指定路径文件所在的文件夹的名称
  11.         if (!Directory.Exists(dirName))
  12.             Directory.CreateDirectory(dirName);  // 在指定的路径下创建一个新的文件夹。
  13.         if (!File.Exists(path))
  14.         {
  15.             thisType.ResetLayer();
  16.             thisType.JsonSaveAs();
  17.             //File.WriteAllText(path, thisType.JsonString());
  18.         }
  19.         // 反序列化后映射類
  20.         T jsonType = thisType.JsonToType<T>();
  21.         ReflectSlef(jsonType, thisType);
  22.     }

  23.     public static void ReflectSlef<T>(T jsonType, T thisType) where T : class
  24.     {
  25.         Dictionary<string, object> dic = [];

  26.         // 获取 jsonType 的所有属性和字段:注意!!!!要加上(BindingFlags.Instance)這個形參!
  27.         Type temptype = jsonType.GetType();
  28.         Type thistype = thisType.GetType();
  29.         PropertyInfo[] tempPpt = temptype.GetProperties(BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Instance);
  30.         PropertyInfo[] thisPpt = thistype.GetProperties(BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Instance);
  31.         FieldInfo[] tempFI = temptype.GetFields(BindingFlags.Public | BindingFlags.SetField | BindingFlags.Instance);
  32.         FieldInfo[] thisFI = thistype.GetFields(BindingFlags.Public | BindingFlags.SetField | BindingFlags.Instance);

  33.         // 遍历属性、字段并输出属性名和值,2024-2-10:注意過濾條件應為可寫、非私有變量。
  34.         for (int i = 0; i < tempPpt.Length; i++)
  35.             if (tempPpt.PropertyType.IsPublic && thisPpt.CanWrite)
  36.                 dic.Add(tempPpt.Name, tempPpt.GetValue(jsonType));
  37.         for (int i = 0; i < tempFI.Length; i++)
  38.             if (thisFI.IsPublic)
  39.                 dic.Add(tempFI.Name, tempFI.GetValue(jsonType));

  40.         for (int i = 0; i < thisPpt.Length; i++)
  41.             if (tempPpt.PropertyType.IsPublic && thisPpt.CanWrite)
  42.                 thisPpt.SetValue(thisType, dic[thisPpt.Name]); // 设置属性值
  43.         for (int i = 0; i < thisFI.Length; i++)
  44.             if (thisFI.IsPublic)
  45.                 thisFI.SetValue(thisType, dic[thisFI.Name]); // 设置字段值
  46.     }

  47.     [MyMethod]
  48.     public static void ReflectSlefFuntion<T>(T thisType) where T : class
  49.     {
  50.         Dictionary<string, object> dic = [];

  51.         // 获取 jsonType 的所有属性和字段:注意!!!!要加上(BindingFlags.Instance)這個形參!
  52.         Type thistype = thisType.GetType();
  53.         MethodInfo[] thisFun = thistype.GetMethods(BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Instance);

  54.         for (int i = 0; i < thisFun.Length; i++)
  55.             thisFun.Equals(dic[thisFun.Name]); // 设置功能
  56.     }


  57. }


關於獲取:
获取dll运行路径 and  添加關鍵字函數
  1. /// <summary>
  2. /// 获取dll运行路径,并添加入注册表供lisp调用
  3. /// </summary>
  4. /// <param name="full">true是含有文件名</param>
  5. /// <returns>当前dll路径</returns>
  6. public static string GetAssemblyPath(bool full)
  7. {
  8.      // 获取程序集的位置 "file:/// G:/K01.惊惊连盒/NET35/JoinBox.dll"
  9.      string path = Assembly.GetExecutingAssembly().CodeBase;
  10.      /*
  11.       * 似乎直接切割比较快
  12.       * path = path.Replace("file:/// ", string.Empty).Replace("/", "\");
  13.       */
  14.      var url = new UriBuilder(path);
  15.      path = Uri.UnescapeDataString(url.Path);// 这里路径是/

  16.      if (full)
  17.          return Path.GetFullPath(path); // 这里是\\
  18.      path = Path.GetDirectoryName(path);// 这里是\\
  19.      var it = path.LastIndexOf('\\');
  20.      if (it != -1)
  21.          path = path[..it] + "\";  // 返回上一级目录
  22.      return path;
  23. }
  24. /// <summary>
  25. /// 添加关键字至设置中
  26. /// </summary>
  27. /// <param name="options">PromptOptions设置</param>
  28. /// <param name="keywords">关键字</param>
  29. public static void AddKeywords(this PromptPointOptions options, List<string> Keywords)
  30. {
  31.      foreach (var key in Keywords)
  32.      {
  33.          if (!options.Keywords.Contains(key))
  34.              options.Keywords.Add(key);
  35.      }
  36. }
  37. /// <summary>
  38. /// 添加关键字至设置中
  39. /// </summary>
  40. /// <param name="options">PromptOptions设置</param>
  41. /// <param name="keywords">关键字</param>
  42. public static void AddKeywords(this PromptEntityOptions options, List<string> Keywords)
  43. {
  44.      foreach (var key in Keywords)
  45.      {
  46.          if (!options.Keywords.Contains(key))
  47.              options.Keywords.Add(key);
  48.      }
  49. }
  50. /// <summary>
  51. /// 添加关键字至设置中
  52. /// </summary>
  53. /// <param name="options">jig设置</param>
  54. /// <param name="keywords">关键字</param>
  55. public static void AddKeywords(this JigPromptPointOptions? options, IEnumerable<string> keywords)
  56. {
  57.      foreach (var key in keywords)
  58.      {
  59.          if (!options!.Keywords.Contains(key))
  60.              options.Keywords.Add(key);
  61.      }
  62. }
复制代码

  1. /// <summary>
  2.    /// 获取枚举类型的所有描述项。
  3.    /// </summary>
  4.    /// <param name="enumType">枚举类型</param>
  5.    /// <returns>返回描述项</returns>
  6.    public static List<string> GetDescriptionList(Type enumType)
  7.    {
  8.        List<string> nameList = [];
  9.        foreach (var e in Enum.GetValues(enumType))
  10.        {
  11.            // 转换成Description后添加至List
  12.            object objArr = e.GetType().GetField(e.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), true)[0];
  13.            nameList.Add(((DescriptionAttribute)objArr).Description);
  14.        }
  15.        return nameList;
  16.    }


備註: 感謝驚驚大佬的關於如何序列化的指教!!!!
          感謝IFOX源碼共享,另此命令參照源泉設計的DF命令設計製作,感謝源泉作者無私分享插件!!!!

上圖中若缺失函數可反饋后修改,上圖中函數可能會有部份源碼在項目的其它文件夾中,未作具體驗證,可回帖后上傳源碼!



 楼主| 发表于 2024-2-20 03:04 | 显示全部楼层
本帖最后由 箭头_Row 于 2024-2-20 03:26 编辑

備註:
// 分割在首尾時萬一超過邊界不能生成直線時的情況
// 2024-2-20:BUG修復:修復 定距、雙線、中心有線模型式下生成錯誤情況,添加try{}  example: 生成的分割線長為440 定距:100 板厚:10 中心有線:是   

  1.   if (centerHasLine)
  2.   {
  3.       for (int i = -(int)Math.Floor((line.Length / 2-thickness/2) / (distension + thickness)); i <= (int)Math.Floor((line.Length / 2 - thickness / 2) / (distension + thickness)); i++)
  4.       {
  5.           //// 分割在首尾時萬一超過邊界不能生成直線時的情況
  6.           //// 2024-2-20:BUG修復:修復 定距、雙線、中心有線模型式下生成錯誤情況,添加try{}  example: 生成的分割線長為440 定距:100 板厚:10 中心有線:是   
  7.           //if (i == -(int)Math.Floor((line.Length / 2) / (distension + thickness)) || i == (int)Math.Floor((line.Length / 2) / (distension + thickness)))
  8.           //{
  9.           //    try
  10.           //    {
  11.           //        AddDivisionPoints(line, listPoints, (distension * i + thickness * (i - 1) + line.Length / 2 + thickness / 2));

  12.           //    }
  13.           //    catch { }
  14.           //    try
  15.           //    {
  16.           //        AddDivisionPoints(line, listPoints, (distension * i + thickness * i + line.Length / 2 + thickness / 2));
  17.           //    }
  18.           //    catch { }
  19.           //}
  20.           //else
  21.           //{
  22.               AddDivisionPoints(line, listPoints, (distension * i + thickness * (i - 1) + line.Length / 2 + thickness / 2));
  23.               AddDivisionPoints(line, listPoints, (distension * i + thickness * i + line.Length / 2 + thickness / 2));
  24.           //}
  25.       }
  26.   }


下方try模式修復BUG的方式捨弃,不是很合理:
  1.   if (centerHasLine)
  2.   {
  3.       for (int i = -(int)Math.Floor((line.Length / 2) / (distension + thickness)); i <= (int)Math.Floor((line.Length / 2) / (distension + thickness)); i++)
  4.       {
  5.           // 分割在首尾時萬一超過邊界不能生成直線時的情況
  6.           // 2024-2-20:BUG修復:修復 定距、雙線、中心有線模型式下生成錯誤情況,添加try{}  example: 生成的分割線長為440 定距:100 板厚:10 中心有線:是   
  7.           if (i == -(int)Math.Floor((line.Length / 2) / (distension + thickness)) || i == (int)Math.Floor((line.Length / 2) / (distension + thickness)))
  8.           {
  9.               try
  10.               {
  11.                   AddDivisionPoints(line, listPoints, (distension * i + thickness * (i - 1) + line.Length / 2 + thickness / 2));

  12.               }
  13.               catch { }
  14.               try
  15.               {
  16.                   AddDivisionPoints(line, listPoints, (distension * i + thickness * i + line.Length / 2 + thickness / 2));
  17.               }
  18.               catch { }
  19.           }
  20.           else
  21.           {
  22.               AddDivisionPoints(line, listPoints, (distension * i + thickness * (i - 1) + line.Length / 2 + thickness / 2));
  23.               AddDivisionPoints(line, listPoints, (distension * i + thickness * i + line.Length / 2 + thickness / 2));
  24.           }
  25.       }
  26.   }

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-6 03:18 , Processed in 0.200535 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表