CAD二次开发(14)-如何实现多条多段线的自动绘制+指定点位置自动绘制图形

1. 需求分析

有时候我们可能需要为CAD用户提供这样的功能:

  1. 用户可以连续点击多个点,然后我们自动为用户绘制多段线。
  2. 用户可以点击多个点,然后在这些点位置自动绘制图形。
  3. 同时需要删除和直线,图形有相交的块BlockReference。

这两个功能怎么实现呢 ?

自动绘制多段线

实现思路:

  1. 提示用户选中需要操作的整个区域图形
  2. 利用选择集筛选出当前区域内块参照所在图层的所有块。
  3. 新建多段线图层。
  4. 开始循环让用户绘制多个多段线。
  5. 再在每个多段线中,递归执行,拾取用户的点操作(PromptPointOptions)。
  6. 把用户的点集合进行分析,进行排序,找出最短路径的连接方式。
  7. 再在指定的图层上进行多段线绘制。
  8. 再利用CAD的相交(IntersectWith)API来判断多段线和哪些块参照有交点。
  9. 删除掉这些相交的块参照即可。

代码如下:

 /// <summary>
        /// 
        /// </summary>
        [CommandMethod("DL")]
        public void AddRoad()
        {
            string layer = CommonConstant.PHALANX_DIVISION_LAYER;
            var doc = Application.DocumentManager.MdiActiveDocument;
            Editor editor = doc.Editor;
            Database db = doc.Database;
            TypedValue[] tv = {
                // 筛选出所有块参照
                new TypedValue((int)DxfCode.Start, "INSERT"),
                // 块参照所在图层
                new TypedValue((int)DxfCode.LayerName, layer)
            };
            SelectionFilter sf = new SelectionFilter(tv);
            PromptSelectionResult psr = editor.GetSelection(sf);
            if (psr.Status == PromptStatus.OK)
            {
                //获取所有选中的块
                SelectionSet ss = psr.Value;
                editor.WriteMessage("\n所选块总数:{0}", ss.Count);
                List<BlockReference> blockReferences = new List<BlockReference>();
                using (Transaction ts = db.TransactionManager.StartTransaction())
                {
                    foreach (SelectedObject so in ss)
                    {
                        BlockReference en = so.ObjectId.GetObject(OpenMode.ForWrite) as BlockReference;
                        blockReferences.Add(en);
                    }
                    ts.Commit();
                }
                //新建图层
                AddLayerResult addLayerResult = LayerTool.AddLayer(db, CommonConstant.ROAD_LAYER);

                int roadNumber = 1;
                bool isContinue = true;
                while (isContinue)
                {
                    int nodeNumber = 1;
                    PromptPointOptions ppo = new PromptPointOptions("\n开始绘制第"+roadNumber+"条多段线的第"+nodeNumber+"个节点的坐标:");
                    PromptPointResult pointResult = editor.GetPoint(ppo);
                    List<Point3d> roadNodes = new List<Point3d>();
                    if (pointResult.Status == PromptStatus.OK)
                    {
                        roadNodes.Add(pointResult.Value);
                        roadService.UserInteraction(roadNodes,roadNumber, nodeNumber, editor);
                        roadService.AddRoad(blockReferences,roadNodes,addLayerResult.layerName);
                    }
                    else
                    {
                        isContinue = false;
                    }
                    roadNumber += 1;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="roadNodes">多段线节点集合</param>
        /// <param name="roadNumber">第几条多段线</param>
        /// <param name="nodeNumber">节点个数</param>
        /// <param name="editor"></param>
        public void UserInteraction(List<Point3d> roadNodes,int roadNumber,int nodeNumber,Editor editor)
        {
            nodeNumber += 1;
            PromptPointOptions ppo = new PromptPointOptions("\n请选择第"+roadNumber+"条多段线的第"+nodeNumber+"个节点的坐标:");
            PromptPointResult pointResult = editor.GetPoint(ppo);
            var point3d = pointResult.Value;
            if (pointResult.Status == PromptStatus.OK)
            {
                roadNodes.Add(point3d);
                UserInteraction(roadNodes,roadNumber,nodeNumber,editor);
            }
        }
   /// <summary>
        /// 
        /// </summary>
        /// <param name="blockReferences"></param>
        /// <param name="roadNodes"></param>
        /// <param name="layerName"></param>
        public void AddRoad(List<BlockReference> blockReferences,List<Point3d> roadNodes,string layerName)
        {
            
            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                if (blockReferences.Count > 0)
                {
                   //找出最短路径连接方式
                    roadNodes = PolylineTool.ShortPathRank(roadNodes);
                    List<Point2d> points2D = roadNodes.Select(p => new Point2d(p.X, p.Y)).ToList();
                    //多段线绘制
                    ObjectId objectId = db.AddPolyLineToModelSpace(false, 10,layerName, points2D.ToArray());
               
                    //删除和多段线相交的块
                    DBObject dbObj = tr.GetObject(objectId, OpenMode.ForWrite);
                    if (dbObj is Polyline)
                    {
                        Polyline polyline = (Polyline)dbObj;
                        //相交
                        List<Point3d> point3ds = new List<Point3d>();
                        for (var i = 0; i < blockReferences.Count; i++)
                        {
                            var intersectWithResult = new Point3dCollection();
                            polyline.IntersectWith(blockReferences[i], Intersect.OnBothOperands, intersectWithResult, IntPtr.Zero, IntPtr.Zero);
                            if (intersectWithResult.Count > 0)
                            {
                                point3ds.Add(blockReferences[i].Position);
                            }
                        }
                        BlockTool.DeleteBlockRefByBlockName(db,CommonConstant.BRACKET_BLOCK_NAME,point3ds);
                    }
                   
                }
                tr.Commit();
            }
            
        }

里面有一些图层操作的工具方法(LayerTool),多段线的工具方法(PolylineTool)后续会给大家分享出来,块删除的方法其实上篇文章已经分享了。
效果如下:
在这里插入图片描述

在这里插入图片描述

指定点位置自动绘制图形

 [CommandMethod("PS")]
        public void AddTransformer()
        {
           string layer = CommonConstant.PHALANX_DIVISION_LAYER;
            var doc = Application.DocumentManager.MdiActiveDocument;
            Editor editor = doc.Editor;
            Database db = doc.Database;
            TypedValue[] tv = {
                // 筛选出所有块
                new TypedValue((int)DxfCode.Start, "INSERT"),
                // 筛选出块所在图层
                new TypedValue((int)DxfCode.LayerName, layer)
            };
            SelectionFilter sf = new SelectionFilter(tv);
            PromptSelectionResult psr = editor.GetSelection(sf);
            if (psr.Status == PromptStatus.OK)
            {
                //获取所有选中的块
                SelectionSet ss = psr.Value;
                editor.WriteMessage("\n所选块总数:{0}", ss.Count);
                List<BlockReference> blockReferences = new List<BlockReference>();
                using (Transaction ts = db.TransactionManager.StartTransaction())
                {
                    foreach (SelectedObject so in ss)
                    {
                        BlockReference en = so.ObjectId.GetObject(OpenMode.ForWrite) as BlockReference;
                        blockReferences.Add(en);
                    }
                    ts.Commit();
                }
                //新建图层
                AddLayerResult addLayerResult = LayerTool.AddLayer(db, CommonConstant.TRANSFORMER_LAYER);
                
                electricService.AddTransformer(blockReferences,addLayerResult,doc);
            }
        }
/// <summary>
        /// 获取位置
        /// </summary>
        /// <param name="blockReferences"></param>
        /// <param name="roadList"></param>
        public void AddTransformer(List<BlockReference> blockReferences, AddLayerResult addLayerResult,Document doc)
        {
            if (blockReferences.Count > 0)
            {
                Editor editor = doc.Editor;
                Database db = doc.Database;
                //根据颜色分组
                var blockReferencesMap = blockReferences.GroupBy(reference => reference.Color)
                    .ToDictionary(group => group.Key, 
                        group => group.ToList());

                var number = blockReferencesMap.Count;
            
                List<Point3d> transformerNodes = new List<Point3d>();
                while (number>0)
                {
                    PromptPointOptions ppo = new PromptPointOptions("\n选中第"+number+"个箱变位置");
                    PromptPointResult pointResult = editor.GetPoint(ppo);
               
                    if (pointResult.Status == PromptStatus.OK)
                    {
                        transformerNodes.Add(pointResult.Value);
                    }
                    number -= 1;
                }
                
                foreach (var transformer in transformerNodes)
                {
                    Dictionary<string, double> dictionary = BlockTool.getBlockMaxBlock(db,blockReferences[0]);
                    ObjectId objectId = db.AddPolygonToModelSpace(new Point2d(transformer.X,transformer.Y),dictionary["maxXSpacing"]/2,5,90,addLayerResult.layerName); 
                
                    using (Transaction tr = doc.TransactionManager.StartTransaction())
                    {
                        DBObject dbObj = tr.GetObject(objectId, OpenMode.ForWrite);
                        if (dbObj is Polyline)
                        {
                            Polyline polyline = (Polyline)dbObj;
                            //相交
                            List<Point3d> point3ds = new List<Point3d>();
                            for (var i = 0; i < blockReferences.Count; i++)
                            {
                                var intersectWithResult = new Point3dCollection();
                                polyline.IntersectWith(blockReferences[i], Intersect.OnBothOperands, intersectWithResult, IntPtr.Zero, IntPtr.Zero);
                                if (intersectWithResult.Count > 0)
                                {
                                    point3ds.Add(blockReferences[i].Position);
                                }
                            }
                            if (point3ds.Count > 0)
                            {
                                //清理周边相交块
                                BlockTool.DeleteBlockRefByBlockName(db,CommonConstant.BRACKET_BLOCK_NAME,point3ds); 
                            }
                            //添加文字
                            TextTool.AddText(db, "PS", new Point2d(transformer.X,transformer.Y), dictionary["maxYSpacing"],addLayerResult.layerName);
                        }
                        tr.Commit();
                    }  
                }
            }
        }

效果如下:
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术闲聊DD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值