123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579 |
- 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<idcoll2.Count;i++)
- {
- Polyline pll = BasicFunction.GetDBObject(idcoll2[i]) as Polyline;
- SelfIntersectDetect(pll, out intersectPts);
- idcoll3.Add(idcoll2[i]);
- if (intersectPts.Count != 0)
- {
- j += intersectPts.Count;
- foreach (Point3d pt in intersectPts)
- {
- Makeflag(pt.X, pt.Y, pt.Z, flagradius, "线自相交点", idcoll3);
- }
- }
- else
- continue;
- }
-
- //将检查后的所有实体添加到块中并移动
- Point3d Self = new Point3d();
- Point3d MoveTo = SelfPt;
- DBObjectCollection objcoll1 = MovebyBlock(idcoll3, 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() + "个交点");
- }
- }
-
- /// <summary>
- /// 线自相交检查
- /// </summary>
- 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<Point3d> vertices = new List<Point3d>();
- 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<Point3d> intersectPts = new List<Point3d>();
- 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<Point3d> interpoint = new List<Point3d>();
- //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<Point3d> interpoint = new List<Point3d>();
- 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() + "处无法判断");
- }
- }
-
-
- /// <summary>
- /// 获取附近多段线
- /// </summary>
- 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;
- }
-
-
- /// <summary>
- /// 线相交检查
- /// </summary>
- private static bool EachIntersect(Polyline oPolyline, Polyline tPolyline, out List<Point3d> intersectPoint3Ds)
- {
- intersectPoint3Ds = new List<Point3d>();
- 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
-
-
- /// <summary>
- /// 将多段线添加到块后将块移动到目标位置并explode
- /// </summary>
- 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;
- }
-
- /// <summary>
- /// 错误标记
- /// </summary>
- 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();
- }
- }
- }
|