首页 > 编程语言 >031集——获取外轮廓(只支持线段多段线)(CAD—C#二次开发入门)

031集——获取外轮廓(只支持线段多段线)(CAD—C#二次开发入门)

时间:2024-11-09 11:45:57浏览次数:3  
标签:Count C# List lines item polyline 二次开发 new 031

此版本跟007集相比,增加了个识别断线头的功能,即原始图形中线段可不闭合。

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace AcTools
{
    public static class Outershape
    {
        public static void Demo()
        {
            try
            {
                
                if (!Z.db.GetEntities(out List<Curve> curve, "框选识别外轮廓的图像") )return;
                List<Line> lines = new List<Line>();
                foreach (var item in curve)//多段线炸开成线段
                {
                    if (item is Line) lines.Add(item as Line);
                    else if (item is Polyline pl)
                    {
                        List<Curve> cus = Z.ed.ExplodePolyLine(pl);
                        foreach (var cu in cus)
                        {
                            if (cu is Line) lines.Add(cu as Line);
                        }
                    }
                }
                //lines.ForEach(line => line.ColorIndex = 1);
                //foreach (var item in lines)
                //{
                //    db.AddEntityToModeSpace(item);
                //}

                //return;
                Dictionary<Line, List<Point3d>> pointsOnLine = new Dictionary<Line, List<Point3d>>();
                foreach (var item in lines)//创建线和对应点组成的字典
                {
                    pointsOnLine.Add(item, new List<Point3d>());
                }
                for (int i = 0; i < lines.Count - 1; i++)
                {
                    for (int j = i + 1; j < lines.Count; j++)
                    {
                        Point3dCollection pos = new Point3dCollection();//创建点集合
                        lines[i].IntersectWith(lines[j], Intersect.OnBothOperands, pos, IntPtr.Zero, IntPtr.Zero);
                        if (pos.Count > 0)
                        {
                            foreach (Point3d item in pos)
                            {
                                pointsOnLine[lines[i]].Add(item);
                                pointsOnLine[lines[j]].Add(item);//获取线段交点的坐标存入字典
                            }
                        }
                    }
                }
                lines.Clear();
                foreach (var item in pointsOnLine)//清理线
                {
                    Line line = item.Key;
                    List<Point3d> points = item.Value;
                    //if (points.Count == 0)
                    //{
                    //    //lines.Add(line);
                    //}
                    //else
                    //{
                        if (points.Count > 1)
                        {
                            points = points.OrderBy(x => line.GetParameterAtPoint(x)).ToList();//点排序
                            Point3dCollection pos = new Point3dCollection();
                            points.ForEach(x => pos.Add(x));//点集合加点
                            DBObjectCollection dbs = line.GetSplitCurves(pos);//线上有多个点,按顺序打断线
                            foreach (var dbobject in dbs)
                            {
                                if (dbobject is Line) lines.Add(dbobject as Line);//一个line被他上面的点打成多个line后加入列表
                            }
                        }
                }
                //}
                List<Line> goodlines = Outershape.RepairLine(lines);//清除线头
                List<Line> goodlines2 = Outershape.RecycleLine(goodlines);
                if (goodlines2.Count == 0) return;
                //foreach (var item in goodlines2)
                //{
                //    item.ChangeEntityColor(2);
                //}
                //Z.db.AddEntityToModeSpace(goodlines2.ToArray());
                //return;
                lines.Clear();
                lines = goodlines2;
                // if (!PmPolyLineMethod.GetPoint(out Point3d point, "请选择外面一点")) return;
                if (! Z.ed.GetPoint(out Point3d point, "请选择外面一点"))return;
                Line firstLine = lines.OrderBy(x => x.GetClosestPointTo(point, false).DistanceTo(point)).First();
                //firstLine.ColorIndex = 5;
                //Z.db.AddEntityToModeSpace(firstLine);
                //return;
                lines.Remove(firstLine);
                Polyline polyline = new Polyline();
                polyline.AddVertexAt(0, firstLine.StartPoint.Convert2d(new Plane()), 0, 0, 0);
                polyline.AddVertexAt(1, firstLine.EndPoint.Convert2d(new Plane()), 0, 0, 0);
                Vector3d v1 = firstLine.StartPoint - point;
                Vector3d v2 = firstLine.EndPoint - point;
                if (v1.CrossProduct(v2).Z > 0) polyline.ReverseCurve();
                //polyline.ColorIndex = 1;
                //db.AddEntityToModeSpace(polyline);
                //return;
                while (true)
                {
                    List<Line> tmps = new List<Line>();
                    foreach (var item in lines)
                    {
                        if (item.StartPoint == polyline.EndPoint)
                        {
                            tmps.Add(item);
                        }

                        else if (item.EndPoint == polyline.EndPoint)
                        {
                            item.ReverseCurve();
                            tmps.Add(item);
                        }
                    }
                    if (tmps.Count == 0) break;
                    Vector3d vector = -polyline.GetFirstDerivative(polyline.EndPoint);//顺时针
                    double maxAngle = 0;
                    Line bigLine = new Line();
                    foreach (var item in tmps)//
                    {
                        double angle = vector.GetAngleTo(item.Delta, -Vector3d.ZAxis);
                        if (angle > maxAngle)
                        {
                            maxAngle = angle;
                            bigLine = item;
                        }
                    }
                    polyline.JoinEntity(bigLine);
                    lines.Remove(bigLine);
                    if (polyline.EndPoint == polyline.StartPoint) break;
                }
                polyline.ColorIndex = 1;
                Z.db.AddEntityToModeSpace(polyline);
                return;
            }

            catch (System.Exception)
            {
                throw;
            }

        }
        public static List<Line> RepairLine(List<Line> lines)
        {
            if (lines.Count == 0 ) return new List<Line>();
            bool leftHandOk = false; 
            bool rightHandOk = false;
            List<Line> goodlines = new List<Line>();
            for (int i = 0; i < lines.Count; i++)
            {       leftHandOk = false;
                    rightHandOk = false;
                //if (i == 6) Debugger.Break();
                Point3d point = new Point3d((lines[i].StartPoint.X + lines[i].EndPoint.X) / 2, (lines[i].StartPoint.Y + lines[i].EndPoint.Y) / 2, 0);
                DBText text = new DBText() { Position = point, TextString = $"{i}:", Height = 1 };
                Z.db.AddEntityToModeSpace(text);
                for (int j = 0; j < lines.Count; j++)
                {
                   
                    if (i == j) continue;
                    if ((lines[i].StartPoint == lines[j].StartPoint)|| (lines[i].StartPoint == lines[j].EndPoint))
                    {
                        leftHandOk = true;
                    }
                    if ((lines[i].EndPoint == lines[j].StartPoint) || (lines[i].EndPoint == lines[j].EndPoint))
                    {
                        rightHandOk = true;
                    }
                    if (leftHandOk && rightHandOk)
                    {
                        if (!goodlines.Contains(lines[i]))
                        {
                            goodlines.Add(lines[i]);
                        }
                        
                    }
                }

            }
            return goodlines;
        }
        public static List<Line> RecycleLine(List<Line> lines)
        {
            if (lines.Count == 0) return new List<Line>();
            List<Line> templine = lines;
            int tempnum = lines.Count;
            while (true)
            {
                if (RepairLine(templine).Count == tempnum)
                {
                    break;
                    
                }
                else
                {
                    templine = RepairLine(templine);
                    tempnum = templine.Count;
                }
            }
            return templine;
        }
    }
}

 

标签:Count,C#,List,lines,item,polyline,二次开发,new,031
From: https://blog.csdn.net/yongshiqq/article/details/143642717

相关文章

  • 基于HTML+CSS+JavaScript仿淘宝购物商城设计毕业论文源码
    常见网页设计作业题材有个人、美食、公司、学校、旅游、电商、宠物、电器、茶叶、家居、酒店、舞蹈、动漫、服装、体育、化妆品、物流、环保、书籍、婚纱、游戏、节日、戒烟、电影、摄影、文化、家乡、鲜花、礼品、汽车、其他等网页设计题......
  • Beyond Compare 5 比较文本文件时,如何忽略字母的大小写差异?
    在BeyondCompare5中实现忽略字母大小写功能,可以按照以下步骤操作:打开文本比较会话:启动BeyondCompare5软件,单击主页面右侧“文本比较”会话图标,打开会话操作界面。单击界面内“打开文件”按钮,浏览并挑选需要比较的文本文件。此时,可能会看到因字母大小写不同而......
  • MMdetection 问题报错 mmdet/evaluation/metrics/coco_metric.py data[‘category_id
    方案一:有人说在自己定义的conifg文件中增加 metainfo={'classes':('class1','class2','class2',),'palette':[(220,20,60),(221,11,22),(221,11,42),]}方案二:修改mmdet/evaluation/metrics文件的内......
  • LeetCode 171[Excel表列序号]
    题目链接LeetCode171[Excel表列序号]详情实例提示题解思路这其实是一道26进制的算术题其中A的权重为1,B的权重为2,C的权重为3,D的权重为4,E的权重为5,F的权重为6,G的权重为7H的权重为8,I的权重为9,J的权重为10,K的权重为11,L的权重为12,M的权重为13N的权重为14,O的权重为15,P的......
  • E. Disrupting Communications
    注意可能出现dpx+1在模意义下为0的情况,此时需要额外维护0的个数而不能求逆元记f[x]表示x子树内包含x的连通子图的个数,g[x]表示全树包含x的连通子图的个数,由于子树的限制,所有fx互斥【子树互斥模型】求出f[x]后换根DP求出g[x]。答案即为u-LCA(u,v)上f的和+g[LCA(u,v)]+v-LCA(u,v......
  • OFA-Sys/chinese-clip-vit-base-patch16 占用显存测试
    model.get_image_features(inputs) 64batch_size2096MB取消withtorch.no_grad():后8GB占满16batch_size3886MB AutoModel.from_pretrained(MODEL_NAME)执行慢,原因是需要启用网络代理,否则总是卡在验证阶段 DataLoader增加num_workers后torch.cuda.OutOf......
  • 手把手教你搭建Windows+YOLO11+CUDA环境,以EMA注意演示如何改进YOLO11, 训练自定义数据
    YOLOv11目标检测创新改进与实战案例专栏文章目录:YOLOv11创新改进系列及项目实战目录包含卷积,主干注意力,检测头等创新机制以及各种目标检测分割项目实战案例专栏链接:YOLOv11目标检测创新改进与实战案例文章目录YOLOv11目标检测创新改进与实战案例专栏前言本......
  • 【YOLO11改进 - 注意力机制】添加YOLO-Face提出的SEAM注意力,提高遮挡情况下的特征学
    YOLOv11目标检测创新改进与实战案例专栏文章目录:YOLOv11创新改进系列及项目实战目录包含卷积,主干注意力,检测头等创新机制以及各种目标检测分割项目实战案例专栏链接:YOLOv11目标检测创新改进与实战案例文章目录YOLOv11目标检测创新改进与实战案例专栏介绍......
  • 【YOLO11改进 - 检测头】Detect-Dyhead检测头:带有注意力机制检测头,较低参数数量的同
    YOLOv11目标检测创新改进与实战案例专栏文章目录:YOLOv11创新改进系列及项目实战目录包含卷积,主干注意力,检测头等创新机制以及各种目标检测分割项目实战案例专栏链接:YOLOv11目标检测创新改进与实战案例文章目录YOLOv11目标检测创新改进与实战案例专栏原理......
  • Pbootcms上传文件大小限制如何处理
    为了提高PBootCMS上传文件的大小限制,需要修改PHP配置文件 php.ini 以及可能涉及的其他配置文件。以下是详细的步骤:一、修改 php.ini 文件打开 php.ini 文件找到PHP安装目录下的 php.ini 文件。通常位于 /etc/php/7.x/fpm/php.ini 或 /etc/php/7.x/cli/php.ini。......