public void calcIntersection(TBPLine tbpline) { Point3dCollection result = new Point3dCollection(); acPline.IntersectWith(tbpline.acPline, Intersect.OnBothOperands, new Plane(new Point3d(0, 0, 0), new Vector3d(0, 0, 1)), result, (IntPtr)0, (IntPtr)0); for (int i = 0; i < result.Count; i++) { Point3d p = result[i]; TBPoint tbp = TBPoint.getNewTBPoint(p); this.addIntersectPoint(tbp); tbpline.addIntersectPoint(tbp); } }
//project to level 0 to find the intersect point static public void CheckElevationDifference() { string msg = string.Empty; double checkDistance = 0.55; Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; HostApplicationServices hs = HostApplicationServices.Current; string outputPath = hs.FindFile(doc.Name, doc.Database, FindFileHint.Default); string logPath = outputPath + "_log.log"; System.IO.File.WriteAllText(logPath, msg); //get user input //select point input file ed.WriteMessage("Select the Excel file contains the door step points"); string excelPath = FileOps.SelectFile(); #region get Excel Sheet Name PromptStringOptions pStrOpts = new PromptStringOptions("\nEnter Sheet Name: "); pStrOpts.AllowSpaces = true; PromptResult pStrRes = doc.Editor.GetString(pStrOpts); string shtName = pStrRes.StringResult; #endregion List <Point3d> doorStepPts = Excel.getAllpoint(doc, excelPath, shtName); PromptEntityResult per = ed.GetEntity("Select polylines"); ObjectId oid = per.ObjectId; ObjectIdCollection oDBO = new ObjectIdCollection(); List <Polyline3d> poly3ds = new List <Polyline3d>(); List <Polyline3d> poly3ds0 = new List <Polyline3d>(); if (per.Status == PromptStatus.OK) { Transaction tr = db.TransactionManager.StartTransaction(); BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false); DBObject objPick = tr.GetObject(oid, OpenMode.ForRead); Entity objEnt = objPick as Entity; string sLayer = objEnt.Layer.ToString(); oDBO = CADops.SelectAllPolyline(sLayer); foreach (ObjectId id in oDBO) { Polyline3d pl = new Polyline3d(); System.IO.File.AppendAllText(logPath, $"{id}\n"); poly3ds0.Add(CADops.CreatePolylineOnXYPlane(doc, id, ref pl)); poly3ds.Add(pl); } } List <Point3d> output = new List <Point3d>(); List <string> data = new List <string>(); if (poly3ds.Count() > 0) { Transaction tr = db.TransactionManager.StartTransaction(); BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false); using (tr) { List <Vector3d> vectorsAlongPath = new List <Vector3d>(); List <Vector3d> vectors = CADops.getVectors(doorStepPts, doc, ref vectorsAlongPath); //foreach (Point3d pt in doorStepPts) for (int i = 0; i < doorStepPts.Count(); i++) { Point3d pt = doorStepPts[i]; Point3d pt0 = new Point3d(pt.X, pt.Y, 0); Vector3d v = vectors[i].GetNormal() * 5; Matrix3d mat = Matrix3d.Displacement(v); Point3d npt = pt0.TransformBy(mat); v = vectors[i].GetNormal() * -5; mat = Matrix3d.Displacement(v); Point3d npt2 = pt0.TransformBy(mat); //create a 2d line in XY plane Line ln = new Line(npt, npt2); btr.AppendEntity(ln); tr.AddNewlyCreatedDBObject(ln, true); msg = $"pt => {pt.X}, {pt.Y}, {pt.Z}\n"; #region get intersect point from point to polyline Point3d ptNearest = Point3d.Origin; for (int j = 0; j < poly3ds0.Count(); j++) { Polyline3d p3d0 = poly3ds0[j]; Polyline3d p3d = poly3ds[j]; Point3d ptTemp = new Point3d(); #region get the alignment object and find the nearest point to the nominated point Point3dCollection pts3D = new Point3dCollection(); p3d0.IntersectWith(ln, Intersect.OnBothOperands, pts3D, IntPtr.Zero, IntPtr.Zero); try { if (pts3D.Count > 0) { double para = p3d0.GetParameterAtPoint(pts3D[0]); //ed.WriteMessage($"{pts3D[0]}, {para}\n"); ptTemp = p3d.GetPointAtParameter(para); } } catch { } #region get the point with lower Z if (ptNearest == Point3d.Origin) { ptNearest = ptTemp; } else { if (ptNearest.Z > ptTemp.Z) { ptNearest = ptTemp; } } #endregion } #endregion #endregion msg += $"ptNearest: {ptNearest.X}, {ptNearest.Y}, {ptNearest.Z}\n"; try { double diff = ptNearest.Z - pt.Z; if (Math.Abs(diff) <= checkDistance) { Point3d newPt = new Point3d(pt.X, pt.Y, ptNearest.Z + checkDistance); output.Add(newPt); data.Add($"{newPt.X},{newPt.Y},{newPt.Z}, less, {diff}, {ptNearest.Z}"); msg += $", Z diff: {diff} => less than {checkDistance} => {newPt.X}, {newPt.Y}, {newPt.Z}\n\n"; } else { Point3d newPt = pt; output.Add(newPt); data.Add($"{newPt.X},{newPt.Y},{newPt.Z}, more, {diff}, {ptNearest.Z}"); msg += $", Z diff: {diff} => more than {checkDistance} => {newPt.X}, {newPt.Y}, {newPt.Z}\n\n"; } } catch { } System.IO.File.AppendAllText(logPath, msg); } tr.Commit(); } } Excel.createCSV(data, outputPath); ed.WriteMessage("\ncsv file has been created under path " + outputPath); }
///<summary> /// Get the intersection points between this planar entity and a curve. ///</summary> ///<param name="cur">The curve to check intersections against.</param> ///<returns>An array of Point3d intersections.</returns> public static Point3d IntersectWith(Point3d pt, Vector3d vect, Polyline3d poly0, Polyline3d poly, double testWidth, Document doc) { Database db = doc.Database; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false); string layerName = CreateAndAssignALayer(Setting.defaultLayerName);//incase if this layer not exist if (layerName == string.Empty) { layerName = "0"; } #region create a 2d line on XY plane in order to find the intersect point for on TBM centerline //create a 2d point Point3d pt0 = new Point3d(pt.X, pt.Y, 0); Vector3d v = vect.GetNormal() * testWidth; Matrix3d mat = Matrix3d.Displacement(v); Point3d npt = pt0.TransformBy(mat); v = vect.GetNormal() * -testWidth; mat = Matrix3d.Displacement(v); Point3d npt1 = pt0.TransformBy(mat); //create a 2d line in XY plane and add to drawing, this use to intersect with TBM alignment, so I can find the point in TBM alignment to create circle Line ln = new Line(npt, npt1); ln.Layer = layerName; btr.AppendEntity(ln); tr.AddNewlyCreatedDBObject(ln, true); //get the alignment object and find the nearest point to the nominated point Point3dCollection pts3D = new Point3dCollection(); Point3d pt_intersect_in_TBM = Point3d.Origin; try { poly0.IntersectWith(ln, Intersect.OnBothOperands, pts3D, IntPtr.Zero, IntPtr.Zero); if (pts3D.Count > 0) { Point3d p = pts3D[0]; DBPoint db_pt = new DBPoint(p); db_pt.Layer = layerName; btr.AppendEntity(db_pt); tr.AddNewlyCreatedDBObject(db_pt, true); try { double para = poly0.GetParameterAtPoint(pts3D[0]);//this is where it will fail, don't know why! //ed.WriteMessage($"{pts3D[0]}, {para}\n"); pt_intersect_in_TBM = poly.GetPointAtParameter(para); return(pt_intersect_in_TBM); } catch { pt_intersect_in_TBM = poly.GetClosestPointTo(p, Vector3d.ZAxis, true);//when GetParameterAtPoint fail, this is should work. but use in caution! } } #endregion } catch { } tr.Commit(); return(pt_intersect_in_TBM); } }