using GrxCAD.DatabaseServices; using GrxCAD.EditorInput; using GrxCAD.Geometry; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace HCTools { public partial class Joinedge_Form : Form { public Joinedge_Form() { InitializeComponent(); } private void Joinedge_Form_Load(object sender, EventArgs e) { this.comboBox_tk.DropDownStyle = ComboBoxStyle.DropDownList; //自动填充下拉框 Database database = GrxCAD.DatabaseServices.HostApplicationServices.WorkingDatabase; using (Transaction traction = database.TransactionManager.StartTransaction()) { //存放所有图层名 List alllayername = new List(); LayerTable layertable = traction.GetObject(database.LayerTableId, OpenMode.ForRead) as LayerTable; foreach (ObjectId objid in layertable) { LayerTableRecord layertablerecord = traction.GetObject(objid, OpenMode.ForRead) as LayerTableRecord; alllayername.Add(layertablerecord.Name); } alllayername.Sort(); for (int i = 0; i < alllayername.Count; i++) { this.comboBox_tk.Items.Add(alllayername[i]); } if (alllayername.Contains("TK")) { int index = alllayername.IndexOf("TK"); this.comboBox_tk.SelectedIndex = index; } traction.Commit(); } } private void button_ok_Click(object sender, EventArgs e) { if (comboBox_tk.Text == "") { MessageBox.Show("请选择分幅图框所在图层"); return; } if (textBox_sele.Text == "") { MessageBox.Show("请输入搜索阈值"); return; } string tklyr = comboBox_tk.Text; joinedge(tklyr); } private void joinedge(string tklyr) { dynamic acadApp = GrxCAD.ApplicationServices.Application.AcadApplication; acadApp.ZoomExtents(); Editor ed = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; Database db = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database; //获取分幅图框 TypedValue[] typedvalue = new TypedValue[2]; typedvalue.SetValue(new TypedValue((int)DxfCode.LayerName, tklyr), 0); typedvalue.SetValue(new TypedValue((int)DxfCode.Start, "Polyline,LWPolyline"), 1); SelectionFilter selectionfilter = new SelectionFilter(typedvalue); PromptSelectionResult psr = ed.SelectAll(selectionfilter); if (psr.Status == PromptStatus.OK) { SelectionSet selectionset = psr.Value; ObjectId[] obj = new ObjectId[selectionset.Count]; obj = selectionset.GetObjectIds(); List selectedid = new List(); for (int i = 0; i < obj.Length; i++) { //获取图幅框信息和与图幅框相交的实体 using (Transaction tr = db.TransactionManager.StartTransaction()) { Entity ent0 = tr.GetObject(obj[i], OpenMode.ForRead) as Entity; Point3dCollection pts = getpt(ent0); selectedid = selebytk(pts, ed, ent0, tr); tr.Commit(); } } //遍历与图框相交的线,在首尾点做框选,如果有被选中的线则做连接 for (int i = 0; i < selectedid.Count; i++) { using (Transaction tr = db.TransactionManager.StartTransaction()) { Entity ent = tr.GetObject(selectedid[i], OpenMode.ForWrite) as Entity; conn(ent, tr, ed); tr.Commit(); } } } } private void sortpts(Point3dCollection ptcoll) { List x = new List(); List y = new List(); for (int i = 0; i < 4; i++) { if (!x.Contains(ptcoll[i].X)) x.Add(ptcoll[i].X); if (!y.Contains(ptcoll[i].Y)) y.Add(ptcoll[i].Y); } if (x[0] > x[1]) { double temp = x[0]; x[0] = x[1]; x[1] = temp; } if (y[0] > y[1]) { double temp = y[0]; y[0] = y[1]; y[1] = temp; } ptcoll[0] = new Point3d(Math.Round(x[0], 3, MidpointRounding.AwayFromZero), Math.Round(y[0], 3, MidpointRounding.AwayFromZero), 0); //左下 ptcoll[1] = new Point3d(Math.Round(x[1], 3, MidpointRounding.AwayFromZero), Math.Round(y[0], 3, MidpointRounding.AwayFromZero), 0); //右下 ptcoll[2] = new Point3d(Math.Round(x[1], 3, MidpointRounding.AwayFromZero), Math.Round(y[1], 3, MidpointRounding.AwayFromZero), 0); //右上 ptcoll[3] = new Point3d(Math.Round(x[0], 3, MidpointRounding.AwayFromZero), Math.Round(y[1], 3, MidpointRounding.AwayFromZero), 0); //左上 } private Point3dCollection getpt(Entity ent) { Point3dCollection ptcoll = new Point3dCollection(); if (ent is Polyline) { Polyline pll = (Polyline)ent; //获取图框节点并排序 int numVertices = pll.NumberOfVertices; for (int j = 0; j < numVertices; j++) { ptcoll.Add(pll.GetPoint3dAt(j)); } sortpts(ptcoll); } else if (ent is Polyline2d) { Polyline2d pl2d = (Polyline2d)ent; pl2d.GetStretchPoints(ptcoll); sortpts(ptcoll); } else if (ent is Polyline3d) { Polyline3d pl3d = (Polyline3d)ent; pl3d.GetStretchPoints(ptcoll); sortpts(ptcoll); } return ptcoll; } private List selebytk(Point3dCollection ptcoll, Editor ed, Entity ent0, Transaction tr) { //设置当前视图 setwindow(ptcoll[0], ptcoll[2], ed); List result = new List(); TypedValue[] typedvalue = new TypedValue[1]; typedvalue.SetValue(new TypedValue((int)DxfCode.Start, "Polyline,LWPolyline"),0); SelectionFilter selectionfilter = new SelectionFilter(typedvalue); PromptSelectionResult psr = ed.SelectCrossingWindow(ptcoll[0], ptcoll[2]); if (psr.Status == PromptStatus.OK) { SelectionSet selectionset = psr.Value; ObjectId[] obj = new ObjectId[selectionset.Count]; obj = selectionset.GetObjectIds(); for (int i = 0; i < obj.Length; i++) { Entity ent = tr.GetObject(obj[i], OpenMode.ForRead) as Entity; if (ent.Layer == comboBox_tk.Text) continue; var plane = new Plane(Point3d.Origin, Vector3d.ZAxis); //选择与图框相交的线将objectid添加到list中 ent0.IntersectWith(ent, Intersect.OnBothOperands, plane, ptcoll, IntPtr.Zero, IntPtr.Zero); if (ptcoll.Count != 0) result.Add(ent.ObjectId); } } return result; } private void conn(Entity ent, Transaction tr, Editor ed) { double sele = double.Parse(textBox_sele.Text); Polyline pll = new Polyline(); Polyline2d pll2d = new Polyline2d(); Polyline3d pll3d = new Polyline3d(); Point3d s_pt = new Point3d(); Point3d e_pt = new Point3d(); if (ent is Polyline) { pll = (Polyline)ent; s_pt = pll.StartPoint; e_pt = pll.EndPoint; } if (ent is Polyline2d) { pll2d = (Polyline2d)ent; s_pt = pll2d.StartPoint; e_pt = pll2d.EndPoint; } if (ent is Polyline3d) { pll3d = (Polyline3d)ent; s_pt = pll3d.StartPoint; e_pt = pll3d.EndPoint; } TypedValue[] typedvalue = new TypedValue[1]; typedvalue.SetValue(new TypedValue((int)DxfCode.Start, "Polyline,LWPolyline"), 0); SelectionFilter selectionfilter = new SelectionFilter(typedvalue); Point3d s_pt1 = new Point3d(s_pt.X - sele, s_pt.Y - sele, 0); Point3d s_pt2 = new Point3d(s_pt.X + sele, s_pt.Y + sele, 0); Point3d e_pt1 = new Point3d(e_pt.X - sele, e_pt.Y - sele, 0); Point3d e_pt2 = new Point3d(e_pt.X + sele, e_pt.Y + sele, 0); setwindow(s_pt1, s_pt2, ed); PromptSelectionResult psr_start = ed.SelectCrossingWindow(s_pt1, s_pt2); setwindow(e_pt1, e_pt2, ed); PromptSelectionResult psr_end = ed.SelectCrossingWindow(e_pt1, e_pt2); if (psr_start.Status == PromptStatus.OK) { SelectionSet selectionset = psr_start.Value; ObjectId[] obj = new ObjectId[selectionset.Count]; obj = selectionset.GetObjectIds(); for (int i = 0; i < obj.Length; i++) { Entity ent1 = tr.GetObject(obj[i], OpenMode.ForWrite) as Entity; if (ent1.Layer == comboBox_tk.Text) continue; if (comp(ent, ent1)) { joinents(ent, ent1, tr); } } } } private bool comp(Entity ent1, Entity ent2) { if (ent1.GetType() == ent2.GetType()) { if (ent1 is Polyline) { Polyline pll1 = (Polyline)ent1; Polyline pll2 = (Polyline)ent2; if (pll1.Layer == pll2.Layer && pll1.Elevation == pll2.Elevation) return true; else return false; } else if (ent1 is Polyline2d) { Polyline2d pll1 = (Polyline2d)ent1; Polyline2d pll2 = (Polyline2d)ent2; if (pll1.Layer == pll2.Layer && pll1.Elevation == pll2.Elevation) return true; else return false; } else if (ent1 is Polyline3d) { Polyline3d pll1 = (Polyline3d)ent1; Polyline3d pll2 = (Polyline3d)ent2; if (pll1.Layer == pll2.Layer) return true; else return false; } else return false; } else return false; } private void setwindow(Point3d pt1, Point3d pt2, Editor ed) { //设置当前视图 ViewTableRecord currview1 = ed.GetCurrentView(); currview1.CenterPoint = new Point2d((pt2.X - pt1.X) / 2 + pt1.X, (pt2.Y - pt1.Y) / 2 + pt1.Y); currview1.Width = pt2.X - pt1.X; currview1.Height = pt2.Y - pt1.Y; ed.SetCurrentView(currview1); } private void joinents(Entity ent1, Entity ent2, Transaction tr) { Database Db = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database; BlockTable Bt = tr.GetObject(Db.BlockTableId, OpenMode.ForWrite) as BlockTable; BlockTableRecord Btr = tr.GetObject(Bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; if (ent1 is Polyline||ent1 is Polyline2d) { Polyline pll1 = new Polyline(); Polyline pll2 = new Polyline(); if (ent1 is Polyline) { pll1 = (Polyline)ent1; pll2 = (Polyline)ent2; } else { Polyline2d pl2d1 = (Polyline2d)ent1; Polyline2d pl2d2 = (Polyline2d)ent2; int ptnum1 = 0; foreach (ObjectId vertexId in pl2d1) { Vertex2d vtx = tr.GetObject(vertexId, OpenMode.ForRead) as Vertex2d; Point2d point = new Point2d(pl2d1.VertexPosition(vtx).X, pl2d1.VertexPosition(vtx).Y); // 获取顶点坐标 double bulge = vtx.Bulge; // 获取凸度 pll1.AddVertexAt(ptnum1, point, bulge, 0, 0); ptnum1++; } pll1.Layer = pl2d1.Layer; pll1.Color = pl2d1.Color; pll1.Linetype = pl2d1.Linetype; pll1.Elevation = pl2d1.Elevation; pll1.Plinegen = pl2d1.LinetypeGenerationOn; pll1.ConstantWidth = pl2d1.ConstantWidth; pll1.Closed = pl2d1.Closed; int ptnum2 = 0; foreach (ObjectId vertexId in pl2d2) { Vertex2d vtx = tr.GetObject(vertexId, OpenMode.ForRead) as Vertex2d; Point2d point = new Point2d(pl2d2.VertexPosition(vtx).X, pl2d2.VertexPosition(vtx).Y); // 获取顶点坐标 double bulge = vtx.Bulge; // 获取凸度 pll2.AddVertexAt(ptnum2, point, bulge, 0, 0); ptnum2++; } pll2.Layer = pl2d2.Layer; pll2.Color = pl2d2.Color; pll2.Linetype = pl2d2.Linetype; pll2.Elevation = pl2d2.Elevation; pll2.Plinegen = pl2d2.LinetypeGenerationOn; pll2.ConstantWidth = pl2d2.ConstantWidth; pll2.Closed = pl2d2.Closed; } if (!pll1.Closed) { if (pll2.StartPoint.DistanceTo(pll1.EndPoint) > Tolerance.Global.EqualPoint) { pll2.ReverseCurve(); // 反转多段线顶点顺序 } // 获取顶点 var vertices = new List(); for (int i = 0; i < pll1.NumberOfVertices; i++) vertices.Add(pll1.GetPoint2dAt(i)); for (int i = 0; i < pll2.NumberOfVertices; i++) vertices.Add(pll2.GetPoint2dAt(i)); // 创建新多段线 var newPline = new Polyline(); for (int i = 0; i < vertices.Count; i++) newPline.AddVertexAt(i, vertices[i], 0, 0, 0); newPline.Layer = pll1.Layer; newPline.Elevation = pll1.Elevation; newPline.Linetype = pll1.Linetype; newPline.Color = pll1.Color; newPline.Plinegen = pll1.Plinegen; newPline.ConstantWidth = pll1.ConstantWidth; Btr.AppendEntity(newPline); tr.AddNewlyCreatedDBObject(newPline, true); } else { // 将多段线转换为曲线集合 DBObjectCollection curves1 = new DBObjectCollection(); curves1.Add(pll1); DBObjectCollection curves2 = new DBObjectCollection(); curves2.Add(pll2); closedjoin(curves1, curves2, Btr, tr,pll1); } } else if(ent1 is Polyline3d) { Polyline3d pl3d1 = (Polyline3d)ent1; Polyline3d pl3d2 = (Polyline3d)ent2; if(!pl3d1.Closed) { Polyline3d pl3d_new = new Polyline3d(); if (pl3d2.StartPoint.DistanceTo(pl3d1.EndPoint) > Tolerance.Global.EqualPoint) { pl3d2.ReverseCurve(); // 反转多段线顶点顺序 } Point3dCollection Verptcoll1 = new Point3dCollection(); pl3d1.GetStretchPoints(Verptcoll1); Point3dCollection Verptcoll2 = new Point3dCollection(); pl3d2.GetStretchPoints(Verptcoll2); foreach (Point3d pt in Verptcoll2) Verptcoll1.Add(pt); foreach(Point3d pt in Verptcoll1) { pl3d_new.AppendVertex(new PolylineVertex3d(pt)); } Btr.AppendEntity(pl3d_new); tr.AddNewlyCreatedDBObject(pl3d_new, true); } else { DBObjectCollection curves1 = new DBObjectCollection(); DBObjectCollection curves2 = new DBObjectCollection(); curves1.Add(pl3d1); curves2.Add(pl3d2); closedjoin(curves1, curves2, Btr, tr, pl3d1); } } } private void closedjoin(DBObjectCollection curves1, DBObjectCollection curves2, BlockTableRecord Btr, Transaction tr, Entity ent) { OutputbyTK_Form ot = new OutputbyTK_Form(); // 创建 Region DBObjectCollection regions1 = new DBObjectCollection(); DBObjectCollection regions2 = new DBObjectCollection(); try { // 将多段线转换为 Region regions1 = GrxCAD.DatabaseServices.Region.CreateFromCurves(curves1); regions2 = GrxCAD.DatabaseServices.Region.CreateFromCurves(curves2); } catch (Exception ex) { GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\n错误: {ex.Message}"); } // 执行布尔运算(并集) GrxCAD.DatabaseServices.Region region1 = (GrxCAD.DatabaseServices.Region)regions1[0]; GrxCAD.DatabaseServices.Region region2 = (GrxCAD.DatabaseServices.Region)regions2[0]; region1.BooleanOperation(BooleanOperationType.BoolUnite, region2); DBObjectCollection explodedCurves = new DBObjectCollection(); region1.Explode(explodedCurves); if (ent is Polyline) { Polyline polyline = ot.createpllfromregion(explodedCurves); Polyline pll1 = (Polyline)ent; polyline.Elevation = pll1.Elevation; polyline.Layer = pll1.Layer; polyline.Color = pll1.Color; polyline.Linetype = pll1.Linetype; polyline.Plinegen = pll1.Plinegen; polyline.ConstantWidth = polyline.ConstantWidth; Btr.AppendEntity(polyline); tr.AddNewlyCreatedDBObject(polyline, true); } else if(ent is Polyline3d) { Polyline3d ply3d_region = ot.createpl3dfromregion(explodedCurves); Polyline3d ply3d = (Polyline3d)ent; ply3d_region.Layer = ply3d.Layer; ply3d_region.Color = ply3d.Color; ply3d_region.Linetype = ply3d.Linetype; ply3d_region.LineWeight = ply3d.LineWeight; } } } }