明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2899|回复: 17

[【IFoxCAD】] 动态坐标标注,示例,附源码

  [复制链接]
发表于 2023-3-1 00:51 | 显示全部楼层 |阅读模式
本帖最后由 d1742647821 于 2023-6-12 11:14 编辑
使用的ifoxcad类库,详见 https://gitee.com/inspirefunction/ifoxcad

一个简单的例子,给大家参考
演示效果



  1. public static class TestClass
  2. {
  3.     private static string appName = "ZBBZ";
  4.     [CommandMethod(nameof(ZBBZ))]
  5.     public static void ZBBZ()
  6.     {
  7.         var r1 = Env.Editor.GetPoint("\n选择标注位置");
  8.         if(r1.Status!=PromptStatus.OK)
  9.             return;
  10.         var pt1 = r1.Value.Ucs2Wcs();
  11.         var ml = new MLeader
  12.         {
  13.             LeaderLineType = LeaderType.StraightLeader,//引线格式-类型:直线
  14.             ContentType = ContentType.MTextContent,//内容-多重引线类型:多行文字
  15.             TextAttachmentType = TextAttachmentType.AttachmentBottomOfTopLine//连接位置:第一行加下划线
  16.         };
  17.         ml.SetDatabaseDefaults();
  18.         ml.SetTextAttachmentType(TextAttachmentType.AttachmentBottomOfTopLine, LeaderDirectionType.LeftLeader);
  19.         ml.SetTextAttachmentType(TextAttachmentType.AttachmentBottomOfTopLine, LeaderDirectionType.RightLeader);
  20.         ml.Annotative = AnnotativeStates.False;
  21.         ml.EnableDogleg = false;//水平基线:否
  22.         ml.DoglegLength = 50;
  23.         var n1 = ml.AddLeader();
  24.         var n2 = ml.AddLeaderLine(n1);
  25.         ml.AddFirstVertex(n2, pt1);
  26.         ml.AddLastVertex(n2, pt1+new Vector3d(1000,1000,0));
  27.         var text = new MText
  28.         {
  29.             Contents = GetBzStr(pt1),
  30.             LineSpacingStyle = LineSpacingStyle.Exactly,
  31.             LineSpacingFactor = 1
  32.         };
  33.         //text.Location = tagPoint;
  34.         ml.MText = text;
  35.         ml.TextHeight = 300;
  36.         ml.SetDogleg(0, Vector3d.XAxis);
  37.         ml.TextAngleType = TextAngleType.HorizontalAngle;
  38.         ml.TextAlignmentType = TextAlignmentType.LeftAlignment;
  39.         using var tr = new DBTrans();
  40.         tr.CurrentSpace.AddEntity(ml);
  41.         tr.RegAppTable.Add(appName);
  42.         ml.XData=new XDataList(){{1001,appName},{1000,GetBzStr(pt1)}};
  43.     }
  44.     /// <summary>
  45.     /// 添加事件
  46.     /// </summary>
  47.     [CommandMethod(nameof(AddEvent))]
  48.     public static void AddEvent()
  49.     {
  50.         Env.Database.ObjectModified -= Database_ObjectModified;
  51.         Env.Database.ObjectModified += Database_ObjectModified;
  52.     }
  53.     /// <summary>
  54.     /// 移除事件
  55.     /// </summary>
  56.     [CommandMethod(nameof(RemoveEvent))]
  57.     public static void RemoveEvent()
  58.     {
  59.         Env.Database.ObjectModified -= Database_ObjectModified;
  60.     }
  61.     private static void Database_ObjectModified(object sender, ObjectEventArgs e)
  62.     {
  63.         var db = (Database)sender;
  64.         if(e.DBObject is not MLeader ml || ml.GetXDataForApplication(appName) is not{} rb)
  65.             return;
  66.         string? oldBz = null;
  67.         foreach (var tv in rb)
  68.         {
  69.             if (tv.TypeCode == 1000)
  70.                 oldBz = tv.Value.ToString();
  71.         }
  72.         if(oldBz is null)
  73.             return;
  74.         var newBz = GetBzStr(ml.GetFirstVertex(0));
  75.         if(newBz==oldBz)
  76.             return;
  77.         db.ObjectModified -= Database_ObjectModified;
  78.         try
  79.         {
  80.             var mt = (MText)ml.MText.Clone();
  81.             mt.Contents = newBz;
  82.             using (ml.ForWrite())
  83.             {
  84.                 ml.MText=mt;
  85.             }
  86.         }
  87.         finally
  88.         {
  89.             db.ObjectModified += Database_ObjectModified;
  90.         }

  91.     }

  92.     private static string GetBzStr(Point3d pt)
  93.     {
  94.         return "X="+ pt.X.ToString("0.00")+"\\PY="+pt.Y.ToString("0.00");
  95.     }
  96. }



顺便贴一下B站主页,里面发了一些教学视频,感谢支持
https://space.bilibili.com/1848261995




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 7明经币 +7 金钱 +55 收起 理由
海阔天空2014 + 1 + 5
qq25469005 + 1 赞一个!
闻人南131 + 1 赞一个!
MUSIC-DIE + 1 很给力!
cghdy + 1
和尚777 + 1 + 50 神马都是浮云
utopio + 1 很给力!

查看全部评分

发表于 2023-3-15 10:03 | 显示全部楼层
pmq 发表于 2023-3-1 19:23
谢谢楼主分享,有没有vb.net 的,C#的看不懂
用 https://converter.telerik.com/ 转换不了。

我也是初学用vb.net做二开,参照楼主的思想和代码改写了一个简化的vb..net代码,但不知道怎么回事,在该对象的modified事件中,不能修改文本值,有高手知道的指点一下。
改写的这个VB.net代码实现模拟拖放mleader。但不能修改坐标值。

  Private Sub CmdCoordMark_Click(sender As Object, e As EventArgs) Handles CmdCoordDim.Click
        Dim acDoc As Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Database = acDoc.Database
        Dim acDocEd As Autodesk.AutoCAD.EditorInput.Editor = acDoc.Editor
        Dim acBlkTbl As BlockTable
        Dim acBlkTblRec As BlockTableRecord
        Using aclckdoc As DocumentLock = acDoc.LockDocument
            Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
                acBlkTbl = CType(acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead), BlockTable)
                acBlkTblRec = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                Dim retStPoint As PromptPointResult = acDocEd.GetPoint(vbLf & "请选择要标注坐标的点:")
                If retStPoint.Status = PromptStatus.OK Then
                Else
                    Exit Sub
                End If
                Dim pt11 As New Point3d(retStPoint.Value.X, retStPoint.Value.Y, 0)

                '得到第二个点的坐标
                '第二点的坐标在第一个坐标的基础上加上一个增量。用来实现leader的拖放,
                '如不这样做, 则需要第二个点才能进行拖放, 在选中第一个点和准备选中第二个点的的时间差,mleader是没有显示出来,影响效果。
                Dim pt22 As New Point3d(retStPoint.Value.X + 0.1, retStPoint.Value.Y + 0.1, 0)

                '设置字体
                Dim acTextStyleTblRec As TextStyleTableRecord = acTrans.GetObject(acCurDb.Textstyle, OpenMode.ForWrite)
                Dim acFont As Autodesk.AutoCAD.GraphicsInterface.FontDescriptor = acTextStyleTblRec.Font
                Dim acNewFont As Autodesk.AutoCAD.GraphicsInterface.FontDescriptor
                acNewFont = New Autodesk.AutoCAD.GraphicsInterface.FontDescriptor("仿宋", False, False, acFont.CharacterSet, acFont.PitchAndFamily)
                acTextStyleTblRec.Font = acNewFont

                '建立多文本
                Dim text As New MText
                text.Contents = GetBzStr(pt11)          '传递第一个点的坐标进行内容变换,注意,本示例代码中,在测绘领域,Cad的X坐标代表的北向。
                text.LineSpacingStyle = LineSpacingStyle.Exactly
                text.LineSpacingFactor = 0.84

                '创建多重引线
                Dim m1 As New MLeader
                m1.LeaderLineType = LeaderType.StraightLeader           '直引线
                m1.ContentType = ContentType.MTextContent
                m1.TextAttachmentType = TextAttachmentType.AttachmentBottomOfTopLine   '1连接位置:第一行加下划线
                m1.SetDatabaseDefaults()

                Dim n1 As Integer = m1.AddLeader()
                Dim n2 As Integer = m1.AddLeaderLine(n1)

                m1.AddFirstVertex(n1, pt11)
                m1.AddLastVertex(n2, pt22)
                m1.MText = text
                m1.TextHeight = 1
                m1.ColorIndex = 3
                m1.ArrowSize = 0.5
                m1.DoglegLength = 0   '基线为0
                m1.LandingGap = 1     '基线与文字的间距为1

                '' 添加新对象到模型空间和事务中   Add the new object to Model space and the transaction
                Dim entNow As List(Of Entity) = New List(Of Entity) From {m1}          '使用对象列表,本示例中只有一个对象,你也可以改写为直接使用mleader
                '调用mleader拖放类
                Dim jigentity As PubMleaderJig = New PubMleaderJig(entNow, New Point3d(retStPoint.Value.X, retStPoint.Value.Y, 0), New Point3d(pt22.X, pt22.Y, 0))
                '在确定具体位置后,把该对象放入数据库中。
                Dim prs As PromptResult = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.Drag(jigentity)
                If prs.Status = PromptStatus.OK Then
                    If prs.Status = PromptStatus.OK Then
                        Dim enti As Entity
                        For Each enti In jigentity.ent
                            acBlkTblRec.AppendEntity(enti)
                            acTrans.AddNewlyCreatedDBObject(enti, True)
                            AddHandler enti.Modified, AddressOf entiModified           '添加该对象的修改事件
                        Next
                    End If
                End If
                acTrans.Commit()
            End Using
        End Using
    End Sub

'对象修改事件,根据楼主的代码改字的
    Private Sub entiModified(ByVal senderObj As Object, ByVal evtArgs As EventArgs)
        Dim m As MLeader = CType(senderObj, MLeader)
        Dim mt As MText = m.MText.Clone
        mt.Contents = GetBzStr(m.GetFirstVertex(0))
        m.UpgradeOpen()           '对象可写
        m.MText = mt                '这句没有运行,不知道为什么,还差什么语句
    End Sub

拖放类
Public Class PubMleaderJig
    '该类专为Mleader拖放使用
    Inherits DrawJig
    Public SecondMovePt As Point3d         '定义第二个插入点
    Public FirstMovePt As Point3d          '定义第一个插入点
    Public ent As List(Of Entity)           '定义多实体对象

    '构造函数
    Public Sub New(ByVal nents As List(Of Entity), ByVal MovePt1 As Point3d, ByVal movePt2 As Point3d)
        'MovePt2为第二个点。movePt1为第一个点,
        MyBase.New()
        SecondMovePt = movePt2
        FirstMovePt = MovePt1
        ent = nents
    End Sub

    '检测鼠标的移动量
    Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
        Dim psr As PromptPointResult = prompts.AcquirePoint                 '接收当前鼠标点的坐标
        If psr.Status = PromptStatus.OK Then                                '确认用户点击了左键
            Dim MovePtNow As Point3d = psr.Value                            '当前鼠标点的坐标赋值给一个新变量
            '鼠标的坐标以第二个点为准移动。
            If (MovePtNow <> SecondMovePt) And MovePtNow.DistanceTo(SecondMovePt) > 0.000001 Then      '判断当前鼠标的坐标与原来的坐标值是否不一样,同时相差值不能小于0.000001
                Dim vector3d As Vector3d = SecondMovePt.GetVectorTo(MovePtNow)    '把原来坐标点转换为顶点值
                Dim matrix As Matrix3d = Matrix3d.Displacement(vector3d)    '
                ent.ForEach(Sub(x) x.TransformBy(matrix))                   '使用lambda转换对象的位置
                SecondMovePt = MovePtNow                                    '把当前的鼠标值赋给保存旧坐标值的变量

                '保持原来第一个点的坐标的值为选中点的坐标
                Dim initpoint As MLeader = CType(ent(0), MLeader)
                initpoint.SetFirstVertex(0, FirstMovePt)
                Return SamplerStatus.OK
            Else
                Return SamplerStatus.NoChange
            End If
            Return SamplerStatus.Cancel
        End If
    End Function

    Protected Overrides Function WorldDraw(draw As GraphicsInterface.WorldDraw) As Boolean
        For Each entt In ent
            draw.Geometry.Draw(entt)             '重绘所有图形
        Next
        Return True
    End Function
End Class
 楼主| 发表于 2023-3-2 08:36 | 显示全部楼层
pmq 发表于 2023-3-1 19:23
谢谢楼主分享,有没有vb.net 的,C#的看不懂
用 https://converter.telerik.com/ 转换不了。

没有                                       
发表于 2023-3-1 19:23 | 显示全部楼层
谢谢楼主分享,有没有vb.net 的,C#的看不懂
https://converter.telerik.com/ 转换不了。
发表于 2023-3-1 08:45 | 显示全部楼层
有没有编译好的?
发表于 2023-3-1 09:54 | 显示全部楼层
资瓷一下,小白666666
发表于 2023-3-1 10:16 | 显示全部楼层
赞赞赞。。。。太好了,学习的好资料
发表于 2023-3-1 11:20 | 显示全部楼层
很不错的示例,学习了
发表于 2023-3-1 13:09 | 显示全部楼层
感谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-26 09:18 , Processed in 3.124688 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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