- using Autodesk.AutoCAD.ApplicationServices; 
- using Autodesk.AutoCAD.DatabaseServices; 
- using Autodesk.AutoCAD.EditorInput; 
- using Autodesk.AutoCAD.Geometry; 
- using Autodesk.AutoCAD.Runtime; 
- using Autodesk.Civil.DatabaseServices; 
- using Autodesk.Civil.DatabaseServices.Styles; 
- using System; 
- using System.Collections.Generic; 
-   
- namespace C3dTest 
- { 
-     public class CreateCurvePipeTest 
-     { 
-         [CommandMethod("CreatePipeFromArc")] 
-         public void CreatePipeFromArc() 
-         { 
-             Document adoc = Application.DocumentManager.MdiActiveDocument; 
-             Editor ed = adoc.Editor; 
-             Database db = adoc.Database; 
-   
-             PromptEntityOptions partOps 
-                 = new PromptEntityOptions("\nSelect network part: "); 
-             partOps.SetRejectMessage("It's not part!"); 
-             partOps.AddAllowedClass(typeof(Part), false); 
-             PromptEntityResult partRes = ed.GetEntity(partOps); 
-             if (partRes.Status != PromptStatus.OK) return; 
-   
-             PromptEntityOptions arcOpts 
-                 = new PromptEntityOptions("\nSelect arc: "); 
-             arcOpts.SetRejectMessage("It's not arc!"); 
-             arcOpts.AddAllowedClass(typeof(Arc), true); 
-             PromptEntityResult arcRes = ed.GetEntity(arcOpts); 
-             if (arcRes.Status != PromptStatus.OK) return; 
-   
-             ObjectId 
-                 netId, 
-                 famId = default, 
-                 sizeId = default; 
-   
-             using (Transaction tr = db.TransactionManager.StartTransaction()) 
-             { 
-                 Part part = tr.GetObject 
-                     (partRes.ObjectId, OpenMode.ForRead) as Part; 
-   
-                 netId = part.NetworkId; 
-   
-                 Network net = tr.GetObject 
-                     (netId, OpenMode.ForRead) as Network; 
-   
-                 ObjectId partsListId = net.PartsListId; 
-   
-                 PartsList partsList 
-                     = tr.GetObject(partsListId, OpenMode.ForRead) as PartsList; 
-   
-                 using (ObjectIdCollection pipeFamsIds 
-                     = partsList.GetPartFamilyIdsByDomain(DomainType.Pipe)) 
-                 { 
-                     if (pipeFamsIds.Count > 0) 
-                     { 
-                         famId = pipeFamsIds[0]; 
-                     } 
-                 } 
-   
-                 if (famId.IsValid) 
-                 { 
-                     PartFamily partFamily 
-                         = tr.GetObject(famId, OpenMode.ForRead) as PartFamily; 
-                     if (partFamily.PartSizeCount > 0) 
-                     { 
-                         sizeId = partFamily[0]; 
-                     } 
-                 } 
-   
-                 tr.Commit(); 
-             } 
-   
-             if (!famId.IsValid || !sizeId.IsValid) 
-             { 
-                 return; 
-             } 
-   
-             ObjectId newPipeId = default; 
-             Point3d? endPoint = null; 
-             List<Point3d> tmp = new List<Point3d>();           
-   
-             using (Transaction tr = db.TransactionManager.StartTransaction()) 
-             { 
-                 Arc arc = tr.GetObject(arcRes.ObjectId, OpenMode.ForRead) as Arc;                
-   
-                 CircularArc3d arc3dForCreate; 
-   
-                 bool isClockWise; 
-   
-                 using (CircularArc3d arc3dForSupport = arc.GetGeCurve() as CircularArc3d) 
-                 { 
-                     // Если дуга больше полукруга 
-                     if ((arc3dForSupport.EndAngle - arc3dForSupport.StartAngle) > Math.PI) 
-                     { 
-                         // Идея такая. Сперва создаём трубу полукругом, а затем конечную точку 
-                         // тащим к тому месту, где она должна быть. При этом, капризное API не 
-                         // даёт сразу перетащить эту точку. Поэтому, перетаскивание делается 
-                         // через череду промежуточных точек. Причём, чем больше получается итоговый 
-                         // центральный угол дуги, тем меньше нужно делать шаг между точками. 
-   
-                         // Сохраняем конечную точку. Одновременно это будет флагом того, что 
-                         // полученную изначально трубу надо будет дотягивать до этой точки 
-                         endPoint = arc3dForSupport.EndPoint; 
-                          
-                         double 
-                             // Почему-то иногда метод отказывается строить полный полукруг. 
-                             // Поэтому чуть-чуть его уменьшаем 
-                             tmpTotalAngle = 0.99 * Math.PI, 
-                             tmpEndAngle = arc3dForSupport.StartAngle + tmpTotalAngle; 
-                          
-                         arc3dForCreate = new CircularArc3d 
-                             (arc3dForSupport.Center, 
-                             arc3dForSupport.Normal, 
-                             arc3dForSupport.ReferenceVector, 
-                             arc3dForSupport.Radius, 
-                             arc3dForSupport.StartAngle, 
-                             tmpEndAngle); 
-   
-                         // Начальный угловой шаг для вычисления точек на дуге 
-                         double 
-                             step = Math.PI / 6.0, 
-                             // Пороговое значение центрального угла дуги 
-                             // для первого уменьшения шага 
-                             stage1 = Math.PI * 1.5, 
-                             // Пороговое значение центрального угла дуги 
-                             // для второго уменьшения шага 
-                             stage2 = Math.PI * 11.0 / 6.0; 
-                          
-                         while ((arc3dForSupport.EndAngle - tmpEndAngle) > step) 
-                         { 
-                             tmpTotalAngle += step; 
-                             tmpEndAngle += step; 
-                             tmp.Add(arc3dForSupport.EvaluatePoint(tmpEndAngle)); 
-   
-                             // Чем больше итоговая дуга - тем меньше шаг 
-                             if (tmpTotalAngle > stage2) 
-                             { 
-                                 step = Math.PI / 36.0; 
-                             } 
-                             else if (tmpTotalAngle > stage1) 
-                             { 
-                                 step = Math.PI / 9; 
-                             }                             
-                         }                         
-                     } 
-                     else 
-                     { 
-                         arc3dForCreate = arc3dForSupport.Clone() as CircularArc3d; 
-                     } 
-   
-                     Plane xy = new Plane(Point3d.Origin, Vector3d.ZAxis); 
-                     Point3d mid = arc3dForSupport.EvaluatePoint 
-                         ((arc3dForSupport.EndAngle + arc3dForSupport.StartAngle) / 2.0); 
-                     using (CircularArc2d arc2d = new CircularArc2d 
-                         (arc3dForSupport.StartPoint.Convert2d(xy), 
-                         mid.Convert2d(xy), 
-                         arc3dForSupport.EndPoint.Convert2d(xy))) 
-                     { 
-                         isClockWise = arc2d.IsClockWise; 
-                     } 
-                 } 
-   
-                 Network net = tr.GetObject(netId, OpenMode.ForWrite) as Network; 
-   
-                 using (arc3dForCreate) 
-                 { 
-                     net.AddCurvePipe 
-                     (famId, 
-                     sizeId, 
-                     arc3dForCreate, 
-                     isClockWise, 
-                     ref newPipeId, 
-                     false); 
-                 } 
-   
-                 tr.Commit(); 
-             } 
-   
-             if (newPipeId.IsValid && endPoint.HasValue) 
-             { 
-                 foreach (Point3d tmpPt in tmp) 
-                 { 
-                     using (Transaction tr = db.TransactionManager.StartTransaction()) 
-                     { 
-                         Pipe pipe = tr.GetObject(newPipeId, OpenMode.ForWrite) as Pipe; 
-                         pipe.EndPoint = tmpPt; 
-                         tr.Commit(); 
-                     } 
-                 } 
-   
-                 using (Transaction tr = db.TransactionManager.StartTransaction()) 
-                 { 
-                     Pipe pipe = tr.GetObject(newPipeId, OpenMode.ForWrite) as Pipe; 
-                     pipe.EndPoint = endPoint.Value; 
-                     tr.Commit(); 
-                 }                 
-             } 
-         } 
-     } 
- } 
-