ADN Open CIS
Сообщество программистов Autodesk в СНГ

15/06/2019

Нахождение геометрического центра для LWPOLYLINE, 3DPoly и 2DPoly

К сожалению, в AutoCAD API нет прямого метода для определения геометрического центра всех трех типов полилиний. Можно использовать библиотеки топологии, чтобы выяснить это. Проще же всего преобразовать LWPOLYLINE, AcDb2dPolyline, AcDb3dPolyline в AcDbRegion в памяти и применить AutoCAD API для получения геометрического центра области (AcDbRegion).

 

Код - C#: [Выделить]
  1. [CommandMethod("GCTR")]
  2. public static void GC() {
  3.  
  4.  var doc = AcCoreApp.DocumentManager.MdiActiveDocument;
  5.  var db = doc.Database;
  6.  var ed = doc.Editor;
  7.  var tid = ObjectId.Null;
  8.  Point2d centroid = Point2d.Origin;
  9.  
  10.  using(Transaction tr = db.TransactionManager.StartTransaction()) {
  11.   try {
  12.  
  13.    TypedValue[] acTypValAr = {
  14.     new TypedValue((int) DxfCode.Operator, "")
  15.    };
  16.    // Назначаем критерий фильтра объекту SelectionFilter
  17.    SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
  18.    // Запрашиваем объекты в области чертежа
  19.    PromptSelectionResult acSSPrompt;
  20.    acSSPrompt = ed.GetSelection(acSelFtr);
  21.  
  22.    // Если статус OK – объекты выбраны
  23.    if (acSSPrompt.Status == PromptStatus.OK) {
  24.     SelectionSet acSSet = acSSPrompt.Value;
  25.     foreach(SelectedObject so in acSSet) {
  26.      var pline = tr.GetObject(so.ObjectId, OpenMode.ForRead) as Entity;
  27.      // Преобразуем объекты в Region в памяти.
  28.      using(DBObjectCollection segments = new DBObjectCollection()) {
  29.       pline.Explode(segments);
  30.       DBObjectCollection regions = Region.CreateFromCurves(segments);
  31.       foreach(Region r in regions) {
  32.        // Находим центроид лежащий в плоскости XY МСК:
  33.        Point3d origin = Point3d.Origin;
  34.        Vector3d xAxis = Vector3d.XAxis;
  35.        Vector3d yAxis = Vector3d.YAxis;
  36.        centroid = r.AreaProperties(ref origin, ref xAxis, ref yAxis).Centroid;
  37.        CenterMarkEntity(centroid);
  38.       }
  39.  
  40.      }
  41.      ed.WriteMessage($ "\nГеометрический центр {pline.GetRXClass().DxfName}:{centroid}");
  42.     }
  43.     tr.Commit();
  44.    }
  45.   } catch (Autodesk.AutoCAD.Runtime.Exception ex) {
  46.    ed.WriteMessage(ex.ToString());
  47.   }
  48.  }
  49.  
  50.  
  51. }
  52.  
  53. public static void CenterMarkEntity(Point2d p) {
  54.   var doc = AcCoreApp.DocumentManager.MdiActiveDocument;
  55.   var db = doc.Database;
  56.   var ed = doc.Editor;
  57.   using(Transaction t = db.TransactionManager.StartTransaction()) {
  58.    short mode = (short) AcCoreApp.GetSystemVariable("PDMODE");
  59.    if (mode == 0) {
  60.     AcCoreApp.SetSystemVariable("PDMODE", 99);
  61.    }
  62.    var ms = t.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite) as BlockTableRecord;
  63.    DBPoint dbPt = new DBPoint(new Point3d(p.X, p.Y, .0)) {
  64.     ColorIndex = 3
  65.    };
  66.    ms.AppendEntity(dbPt);
  67.    t.AddNewlyCreatedDBObject(dbPt, true);
  68.    t.Commit();
  69.  
  70.   }
  71.  }

 

Источник: https://adndevblog.typepad.com/autocad/2019/03/detecting-geometric-center-for-lwpolyline-3dpoly-and-2dpoly.html

Автор перевода: Александр Ривилис

Обсуждение: http://adn-cis.org/forum/index.php?topic=

Опубликовано 15.06.2019
Отредактировано 15.06.2019 в 20:23:04