这是一些比较散乱的关于Mline的记录,需要用到C#的Teigha(CAD)库进行操作,我需要对一些Mline自动判题的效果,把错误的绘制在另一个图层显示出来,由于Teigha需要using的关系,我在设计的一开始采用了自建基本数据类型,多次进行using访问的方式进行数据提取操作,然而这样的设计在另一个图层绘制的时候,Mline这个方法却多次造成了我开发的困境。

因此2021.9.16~2021.9.18这三天的工作内容做一个汇总的笔记:

1.多线和多线段的区别

多线段polyline,早期的CAD绘制连续线段的概念,可以添加圆弧,修改线性等操作,属于比较早期的创建方式。

多线mline,增加更多功能的polyline,拥有更多的功能,使用需要定义使用一个mlineStyle(多线样式),进行创建,比如本项目需要创建的多线就必须用到mline,其属于一个多重线段效果是这样:

(如图效果,多条平行线构成的多线效果)

中文网上关于多线的资源往往描述为polyline而不是mline,这使得我在找相关资料的时候变得十分难受。

2.官方对于mline一些常用功能的描述

参考链接,下面内容为机械翻译 + 一些自己的见解:

https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Core/files/GUID-A6839A41-0D81-44F2-953A-220307F9380A-htm.html

创建多条平行线段

Start point:起点

指定多线的下一个顶点。如果创键具有多个线段的多线,提示将会包括Close(闭合)选项

Next point:下一个点
将下一个点作为继续输入的点
Undo: 撤销Next Point操作
Close: 闭合,将所创建的点自动闭合

Justification

确定如何在指定的点之间绘制多线,分别有如下方法构成:

  • Top
  • Zero
  • Bottom
Top: 在光标下方绘制多线,以便具有最大正偏移的线位于指定点处。

Zero: 以光标为中心绘制多线,使 MLSTYLE 元素属性偏移量为 0.0 位于指定点。

Bottom: 在光标上方绘制多线,以便具有最大负偏移的线位于指定点处。

Scale:(缩放)

在一些网上搜索关于mline的例子,基本上每一个mline的创建都需要手动指定

mline.scale = 0; // 表示单根线

mline.scale = 1; // 表示已被的线宽

原文:

Controls the overall width of the multiline. This scale does not affect linetype scale.

 

The scale factor is based on the width established in the multiline style definition. A scale factor of 2 produces a multiline twice as wide as the style definition. A negative scale factor flips the order of the offset line—the smallest on top when the multiline is drawn from left to right. A negative scale value also alters the scale by the absolute value. A scale factor of 0 collapses the multiline into a single line.

控制多线的总宽度。 此比例不会影响线型比例。

比例因子基于多线样式定义中建立的宽度。 比例因子为 2 会产生两倍于样式定义宽度的多行。 负比例因子会翻转偏移线的顺序——当从左到右绘制多线时,偏移线的顺序是最小的。 负比例值也会按绝对值改变比例。 比例因子为 0 会将多行折叠为单行。

Style :指定用于多线的样式。

3.相关的代码

在一个案例中,mline创建为:

Mline mine = (Mline)TemporaryEnt;  // 从临时实体中创建
mine.Scale = 0;
if (mine.NumberOfVertices <= 1)
{
    mine.AppendSegment(toEyeToWorld(X, Y));
}
else
{
    Point3d po = mine.VertexAt(mine.NumberOfVertices - 1);
    mine.RemoveLastSegment(out po);
    mine.AppendSegment(toEyeToWorld(X, Y));
}
//toEyeToWorld 为通过显示界面返回实际画布的三维坐标值(Z为0)

我需要创建四条线的数据,获取多线线数的方式是 mline.Elements.Count; 然而就如同List方法一样,这是只能get的,因而,具体创建多线数的表示方法就需要手动创建ELements的细节实现,然而这个非常的困难(缺少具体效果的资料),从而我改成,基于原始错误的多线进行复制。

接下来的问题就出现了,当初为了获取信息的简略,我采用自己创建数据基类的方式存储数据,(只保存我需要筛选的关键数据)而避免多次遍历造成的代码冗余,而在此时绘制的时候,已经脱离了原有的using空间区域了,后续,我想了一个办法,存储每一个vet_point(多线的端点)的坐标,遍历两次进行比对,这样的缺点是使用了更多的内存,和CPU使用,但是作为一个取巧的方式,最终还是实现了错误多线的定位并且在其他的图层绘制出来效果。

参考的代码如下:

            using (var trans = database.TransactionManager.StartTransaction())
            {
                BlockTableRecord btrec = trans.GetObject(database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                // 转换成实体
                foreach(ObjectId objid in btrec)
                {
                    Entity ent = trans.GetObject(objid, OpenMode.ForWrite) as Entity;
                    if (ent.GetType().Name.Contains("Mline"))
                    {
                        Mline dbtxta = (Mline)ent;
                        if (dbtxta.Layer != ori_layer) continue;
                        MlineStyle mlsta = ((MlineStyle)dbtxta.Style.GetObject(OpenMode.ForRead));  // 多线样式
                        bool flag = true;
                        for (int i = 0; i < dbtxta.NumberOfVertices && xyz.Count == dbtxta.NumberOfVertices; i++)
                        {
                            // 如果存在一个不满足,则置flag为否
                            if(xyz[i].X != dbtxta.VertexAt(i).X || 
                                xyz[i].Y != dbtxta.VertexAt(i).Y ||
                                xyz[i].Z != dbtxta.VertexAt(i).Z)
                            {
                                flag = false;
                            }
                        }
                        // 如果该线段满足位置要求,则复制一个新的放在错误图层中
                        if (flag)
                        {
                            // 通过拷贝的方式在新图层创建这个变量
                            Mline mline = dbtxta.Clone() as Mline;
                            btrec.AppendEntity(mline);
                            mline.Layer = LayerName;    // 添加到图层
                            trans.AddNewlyCreatedDBObject(mline, true);
                        }
                    }

                }
                // 事务提交
                trans.Commit();
                // 保存
                database.Save();
            }

xyz结构,只是自己设计的快捷存储了double x,double y,double z这三个变量,没有直接使用Point3D

最终的效果:

绿色的线段表示绘制错误,在新建的错误图层绘制,红色的为正确线段

分类: C#

0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注