static public void CreateTunnel() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; //=========== Matrix3d curUCSMatrix = doc.Editor.CurrentUserCoordinateSystem; CoordinateSystem3d curUCS = curUCSMatrix.CoordinateSystem3d; double TunnelDia = 6.04; PromptEntityResult per = ed.GetEntity("Select polylines"); ObjectId oid = per.ObjectId; if (per.Status == PromptStatus.OK) { 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); DBObject objPick = tr.GetObject(oid, OpenMode.ForRead); Entity objEnt = objPick as Entity; string sLayer = objEnt.Layer.ToString(); ObjectIdCollection oDBO = CADops.SelectAllPolyline(sLayer); List <string> data = new List <string>(); foreach (ObjectId id in oDBO) { //get 3d polyline Polyline3d poly3d = tr.GetObject(id, OpenMode.ForRead) as Polyline3d; //get points on 3d polyline List <Point3d> pts0 = CADops.GetPointsFrom3dPolyline(poly3d, doc); List <Point3d> pts = pts0.Distinct(new PointComparer(3)).ToList(); //get vectors on points List <Vector3d> vectorAlongPath = new List <Vector3d>(); List <Vector3d> vectors = CADops.getVectors(pts, doc, ref vectorAlongPath); List <LoftProfile> loftProfiles = new List <LoftProfile>(); for (int i = 0; i < pts.Count(); i = i + 4) { Point3d pt = pts[i]; //ed.WriteMessage($"TUN_CreateTBM => {pt.X}, {pt.Y}, {pt.Z}; "); Vector3d v = vectors[i].GetNormal() * TunnelDia / 2; Matrix3d mat = Matrix3d.Displacement(v); Point3d npt = pt.TransformBy(mat); //create a 2d line in XY plane Line ln = new Line(npt, pt); btr.AppendEntity(ln); tr.AddNewlyCreatedDBObject(ln, true); double ang = ln.Angle; //vectors[i].GetAngleTo(curUCS.Xaxis); //ed.WriteMessage($"angle {ang}\n"); Region acRegion = new Region(); try { using (Circle acCirc = new Circle()) { acCirc.Center = new Point3d(pt.X, pt.Y, pt.Z); acCirc.Radius = TunnelDia / 2; acCirc.TransformBy(Matrix3d.Rotation(Angle.angToRad(90), curUCS.Xaxis, acCirc.Center)); acCirc.TransformBy(Matrix3d.Rotation(ang, curUCS.Zaxis, acCirc.Center)); // Add the new object to the block table record and the transaction btr.AppendEntity(acCirc); tr.AddNewlyCreatedDBObject(acCirc, true); DBObjectCollection acDBObjColl = new DBObjectCollection(); acDBObjColl.Add(acCirc); DBObjectCollection myRegionColl = new DBObjectCollection(); myRegionColl = Region.CreateFromCurves(acDBObjColl); Region acRegion1 = myRegionColl[0] as Region; // Add the new object to the block table record and the transaction btr.AppendEntity(acRegion1); tr.AddNewlyCreatedDBObject(acRegion1, true); LoftProfile lp1 = new LoftProfile(acRegion1); loftProfiles.Add(lp1); } } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage(ex.ToString()); } } LoftProfile[] lps = new LoftProfile[loftProfiles.Count()]; for (int i = 0; i < loftProfiles.Count(); i++) { lps[i] = loftProfiles[i]; } try { // =========== create loft solid Solid3d sol = new Solid3d(); sol.SetDatabaseDefaults(); LoftOptions lpOptions = new LoftOptions(); //LoftProfile lpGuide = new LoftProfile(acLine);//create loft profile //LoftProfile[] guideToLoft = new LoftProfile[1] { lpGuide }; //sol.CreateLoftedSolid(lps, guideToLoft, null, lpOptions);//guide to loft can not be null, this parameter is not optional sol.CreateLoftedSolid(lps, null, null, lpOptions); sol.Layer = sLayer;//assign layer //=============save it into database Autodesk.AutoCAD.DatabaseServices.Entity ent = sol;//this is created for using hyperlink btr.AppendEntity(ent); tr.AddNewlyCreatedDBObject(ent, true); } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage(ex.ToString()); } } tr.Commit(); } } }