using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using GrxCAD.ApplicationServices; using GrxCAD.DatabaseServices; using GrxCAD.EditorInput; using GrxCAD.Geometry; namespace HCTools { class Inters { public static int blc;//比例尺 public static string jqx; public static string sqx; //由于AUTOCAD的IntersectWith()函数在实体离开原点过远的情况下精确度会大幅下降, //在进行相交检查时需要将待检查的实体都添加到一个块中,移动块到原点再进行检查, //将检查后的标记也添加到块中,检查完后移动回原位。 #region 线自相交 public void SelfInts() { double flagradius = 4.0 * blc / 1000;//画圆标记半径 string layername = jqx + "," + sqx; Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; TypedValue[] value = new TypedValue[] { new TypedValue((int)DxfCode.LayerName,layername), new TypedValue((int)DxfCode.Start,"LWPOLYLINE") };//设置筛选条件 SelectionFilter filter = new SelectionFilter(value);//选择区域中全部对象 //PromptSelectionResult psr = ed.SelectAll(filter);// 要求在图形区域中手动选择对象 PromptSelectionResult psr = ed.GetSelection(filter); if (psr.Status == PromptStatus.OK) { Point3dCollection intersectPts = new Point3dCollection(); int j = 0; SelectionSet ss = psr.Value; if (ss == null) return; //创建标注相交点符号的图层 LayerControl layerscontrol = new LayerControl(); string layname = "线自相交点"; if (!layerscontrol.haslayername(layname)) { colorgb col = new colorgb(255, 0, 255); layerscontrol.creatlayer(layname, col); layerscontrol.movelayertofront(layname); } else layerscontrol.movelayertofront(layname); ObjectIdCollection idcoll1 = new ObjectIdCollection(ss.GetObjectIds());//需要添加到块中的实体 ObjectIdCollection idcoll2 = new ObjectIdCollection();//explode后重新添加到数据库的实体 ObjectIdCollection idcoll3 = new ObjectIdCollection();//添加标记后实体 Point3d MoveToPt = new Point3d(0, 0, 0);//目标点 Point3d SelfPt = new Point3d();//基点 //将选中多段线添加到块中并移动 DBObjectCollection objcoll = MovebyBlock(idcoll1, out SelfPt, MoveToPt); //将explode之后的实体重新添加到数据库中并检查是否自相交 foreach (Polyline ent in objcoll) { DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTable blocktable = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable; BlockTableRecord blocktablerecord = trans.GetObject(blocktable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; blocktablerecord.AppendEntity(ent); trans.AddNewlyCreatedDBObject(ent, true); idcoll2.Add(ent.Id); trans.Commit(); } doclock.Dispose(); } for(int i =0;i /// 线自相交检查 /// private static bool SelfIntersectDetect(Polyline pPolyline, out Point3dCollection intersectPoint3Ds) { intersectPoint3Ds = new Point3dCollection(); try { // 自身与自身相交结果(包含顶点和相交点) var intersectWithResult = new Point3dCollection(); //pPolyline.IntersectWith(pPolyline, Intersect.OnBothOperands, intersectWithResult, IntPtr.Zero, IntPtr.Zero); // 存储顶点 List vertices = new List(); int count = pPolyline.NumberOfVertices; for (int j = 0; j < count; j++) { Point3d pt = pPolyline.GetPoint3dAt(j); //Point3d pt1 = new Point3d(Math.Round(pt.X, 6), Math.Round(pt.Y, 6), Math.Round(pt.Z, 6)); vertices.Add(pt); } for (int i = 0; i < count - 2; i++) { LineSegment3d lsgment0 = pPolyline.GetLineSegmentAt(i); for (int ii = i + 1; ii < count - 1; ii++) { LineSegment3d lsgment1 = pPolyline.GetLineSegmentAt(ii); Point3d[] itpt = lsgment0.IntersectWith(lsgment1); if (itpt != null) { foreach (Point3d pt in itpt) { intersectWithResult.Add(pt); } } } if (i == 0) { if (intersectWithResult.Count > 1) { for (int j = 0; j < intersectWithResult.Count - 1; j++) { for (int jj = j + 1; jj < intersectWithResult.Count; jj++) { if (intersectWithResult[j] == intersectWithResult[jj]&& !intersectPoint3Ds.Contains(intersectWithResult[jj])) { intersectPoint3Ds.Add(intersectWithResult[jj]); } } } foreach (Point3d pt in intersectWithResult) { if (pt == vertices[1]) continue; else { if(!intersectPoint3Ds.Contains(pt)) intersectPoint3Ds.Add(pt); } } } } else if (i == count - 3) { if (intersectWithResult.Count > 1) { for (int j = 0; j < intersectWithResult.Count - 1; j++) { for (int jj = j + 1; jj < intersectWithResult.Count; jj++) { if (intersectWithResult[j] == intersectWithResult[jj] && !intersectPoint3Ds.Contains(intersectWithResult[jj])) { intersectPoint3Ds.Add(intersectWithResult[jj]); } } } foreach (Point3d pt in intersectWithResult) { if (pt == vertices[i]) continue; else { if (!intersectPoint3Ds.Contains(pt)) intersectPoint3Ds.Add(pt); } } } } else { if (intersectWithResult.Count > 1) { for (int j = 0; j < intersectWithResult.Count - 1; j++) { for (int jj = j + 1; jj < intersectWithResult.Count; jj++) { if (intersectWithResult[j] == intersectWithResult[jj] && !intersectPoint3Ds.Contains(intersectWithResult[jj])) { intersectPoint3Ds.Add(intersectWithResult[jj]); } } } foreach (Point3d pt in intersectWithResult) { if (pt == vertices[i]||pt == vertices[i + 1]) continue; else { if (!intersectPoint3Ds.Contains(pt)) intersectPoint3Ds.Add(pt); } } } } intersectWithResult.Clear(); } return true; } catch (Exception ex) { string str = ex.ToString(); Application.ShowAlertDialog(str); return false; } } #endregion #region 线相交 public void Ints() { double flagradius = 4.0 * blc / 1000;//画圆标记半径 Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; string layername = jqx + "," + sqx; TypedValue[] value = new TypedValue[] { new TypedValue((int)DxfCode.LayerName,layername), new TypedValue((int)DxfCode.Start,"LWPOLYLINE") };//设置筛选条件 SelectionFilter filter = new SelectionFilter(value);//选择区域中全部对象 //PromptSelectionResult psr = ed.SelectAll(filter);// 要求在图形区域中手动选择对象 PromptSelectionResult psr = ed.GetSelection(filter); if (psr.Status == PromptStatus.OK) { List intersectPts = new List(); int j = 0; SelectionSet ss = psr.Value; if (ss == null) return; //创建标注相交点符号的图层 LayerControl layerscontrol = new LayerControl(); string layname = "线相交点"; if (!layerscontrol.haslayername(layname)) { colorgb col = new colorgb(0, 0, 255); layerscontrol.creatlayer(layname, col); layerscontrol.movelayertofront(layname); } else layerscontrol.movelayertofront(layname); ObjectIdCollection idcoll1 = new ObjectIdCollection(ss.GetObjectIds());//需要添加到块中的实体 ObjectIdCollection idcoll2 = new ObjectIdCollection();//explode之后的实体 Point3d MoveToPt = new Point3d(0, 0, 0);//目标点 Point3d SelfPt = new Point3d();//基点 //将选中多段线添加到块中并移动 DBObjectCollection objcoll = MovebyBlock(idcoll1, out SelfPt, MoveToPt); //将explode之后的实体重新添加到数据库中 foreach (Entity ent in objcoll) { DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTable blocktable = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable; BlockTableRecord blocktablerecord = trans.GetObject(blocktable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; blocktablerecord.AppendEntity(ent); trans.AddNewlyCreatedDBObject(ent, true); idcoll2.Add(ent.Id); trans.Commit(); } doclock.Dispose(); } #region//检查线相交情况 ////检查线相交情况 //int num = 0; //int numb = 0;//记录无法判断的实体数量 //ObjectIdCollection objidcoll_check = new ObjectIdCollection(); //List interpoint = new List(); //for (int i = 0; i < objcoll.Count; i++) //{ // DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); // using (Transaction trans = db.TransactionManager.StartTransaction()) // { // Polyline pll1 = trans.GetObject(objcoll[i].Id, OpenMode.ForWrite) as Polyline; // ObjectIdCollection pllids = GetIntersectPlline(pll1,out num);//获取附近多段线 // numb = numb + num; // //根据获取的多段线进行相交检查 // for (int ii = 0; ii < pllids.Count; ii++) // { // if (objidcoll_check.Contains(pllids[ii])) // continue; // Polyline pll2 = trans.GetObject(pllids[ii], OpenMode.ForWrite) as Polyline; // EachIntersect(pll1, pll2, out intersectPts); // foreach (Point3d pt in intersectPts) // { // interpoint.Add(pt); // } // } // if (intersectPts.Count != 0) // objidcoll_check.Add(objcoll[i].Id); // trans.Commit(); // doclock.Dispose(); // } //} #endregion //检查线相交情况 ObjectIdCollection objidcoll_check = new ObjectIdCollection(); List interpoint = new List(); for (int i = 0; i < objcoll.Count - 1; i++) { DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); using (Transaction trans = db.TransactionManager.StartTransaction()) { Polyline pll1 = trans.GetObject(objcoll[i].Id, OpenMode.ForWrite) as Polyline; for (int ii = i + 1; ii < objcoll.Count; ii++) { Polyline pll2 = trans.GetObject(objcoll[ii].Id, OpenMode.ForWrite) as Polyline; EachIntersect(pll1, pll2, out intersectPts); foreach (Point3d pt in intersectPts) { interpoint.Add(pt); } } if (intersectPts.Count != 0) objidcoll_check.Add(objcoll[i].Id); trans.Commit(); doclock.Dispose(); } if (interpoint.Count != 0) { j = interpoint.Count; foreach (Point3d pt in interpoint) { Makeflag(pt.X, pt.Y, pt.Z, flagradius, "线相交点", idcoll2); } } } //将检查后的实体都添加到块中并移动 Point3d Self = new Point3d(); Point3d MoveTo = SelfPt; DBObjectCollection objcoll1 = MovebyBlock(idcoll2, out Self, MoveTo); //将explode之后的实体添加到数据库中 foreach (Entity ent in objcoll1) { ObjectIdCollection idcoll = new ObjectIdCollection(); DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTable blocktable = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable; BlockTableRecord blocktablerecord = trans.GetObject(blocktable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; blocktablerecord.AppendEntity(ent); trans.AddNewlyCreatedDBObject(ent, true); DrawOrderTable orderTable = trans.GetObject(blocktablerecord.DrawOrderTableId, OpenMode.ForWrite) as DrawOrderTable; idcoll.Add(ent.Id); orderTable.MoveToBottom(idcoll); trans.Commit(); } doclock.Dispose(); } ed.WriteMessage("有" + j.ToString() + "个交点"); //ed.WriteMessage("\n有" + numb.ToString() + "处无法判断"); } } /// /// 获取附近多段线 /// private static ObjectIdCollection GetIntersectPlline(Polyline pll, out int num) { num = 0; ObjectIdCollection objidcoll = new ObjectIdCollection(); DBObjectCollection objcoll = new DBObjectCollection(); Editor editor = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; Point3dCollection ptcoll = new Point3dCollection(); //检查是否有相交线 pll.GetStretchPoints(ptcoll); TypedValue[] vl = new TypedValue[] { new TypedValue((int)DxfCode.LayerName,"8110,8120"), new TypedValue((int)DxfCode.Start,"LWPOLYLINE") };//设置筛选条件 SelectionFilter selefilter = new SelectionFilter(vl);//选择区域中全部对象 //PromptSelectionResult psr = ed.SelectAll(filter);// 要求在图形区域中手动选择对象 //SelectFence()无法找到不在当前视图的实体,需要将视图转移到实体所在的位置 dynamic acadApp = Application.AcadApplication; acadApp.ZoomExtents(); PromptSelectionResult seleresult = editor.SelectFence(ptcoll, selefilter); acadApp.ZoomPrevious(); if (seleresult.Status == PromptStatus.OK) { SelectionSet selectionset = seleresult.Value; objidcoll = new ObjectIdCollection(selectionset.GetObjectIds()); if (objidcoll.Contains(pll.Id)) objidcoll.Remove(pll.Id); } return objidcoll; } /// /// 线相交检查 /// private static bool EachIntersect(Polyline oPolyline, Polyline tPolyline, out List intersectPoint3Ds) { intersectPoint3Ds = new List(); try { //两线相交结果 var intersectWithResult = new Point3dCollection(); double temp = oPolyline.Elevation; oPolyline.Elevation = tPolyline.Elevation; oPolyline.IntersectWith(tPolyline, Intersect.OnBothOperands, intersectWithResult, IntPtr.Zero, IntPtr.Zero); if (intersectWithResult.Count!=0) { for (int i = 0; i < intersectWithResult.Count; i++) intersectPoint3Ds.Add(intersectWithResult[i]); } oPolyline.Elevation = temp; return true; } catch (Exception ex) { string str = ex.ToString(); Application.ShowAlertDialog(str); return false; } } #endregion /// /// 将多段线添加到块后将块移动到目标位置并explode /// private static DBObjectCollection MovebyBlock(ObjectIdCollection idcoll, out Point3d SelfPt, Point3d MoveToPt) { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; DBObjectCollection objcoll = new DBObjectCollection();//explode后的实体 ObjectId btrid = new ObjectId();//块id DocumentLock documentlock1 = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable; BlockTableRecord btr = new BlockTableRecord(); Polyline pll = trans.GetObject(idcoll[0], OpenMode.ForRead) as Polyline; btr.Name = "BLK"; bt.UpgradeOpen(); btrid = bt.Add(btr); trans.AddNewlyCreatedDBObject(btr, true); btr.AssumeOwnershipOf(idcoll); btr.Origin = pll.StartPoint; SelfPt = pll.StartPoint; BlockTableRecord ms = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); BlockReference br = new BlockReference(pll.StartPoint, btrid); Vector3d acVec3d = SelfPt.GetVectorTo(MoveToPt); br.TransformBy(Matrix3d.Displacement(acVec3d)); ms.AppendEntity(br); trans.AddNewlyCreatedDBObject(br, true); br.Explode(objcoll); btr.UpgradeOpen(); btr.Erase(); trans.Commit(); } documentlock1.Dispose(); return objcoll; } /// /// 错误标记 /// private void Makeflag(double x, double y, double z, double radius, string layername, ObjectIdCollection idcoll) { Database database = HostApplicationServices.WorkingDatabase; DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); using (Transaction traction = database.TransactionManager.StartTransaction()) { BlockTable blocktable = traction.GetObject(database.BlockTableId,OpenMode.ForWrite) as BlockTable; BlockTableRecord blocktablerecord = traction.GetObject(blocktable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; Circle circ = new Circle(); circ.Center = new Point3d(x, y, z); circ.Radius = radius; circ.Normal = new Vector3d(0, 0, 1); circ.SetDatabaseDefaults(); circ.Layer = layername; blocktablerecord.AppendEntity(circ); traction.AddNewlyCreatedDBObject(circ, true); idcoll.Add(circ.Id); traction.Commit(); //traction.Dispose(); } doclock.Dispose(); } } }