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

31/05/2020

Определение геометрического центра LWPOLYLINE, 2DPoly и 3DPoly

Detecting Geometric Center for LWPOLYLINE, 3DPoly and 2DPoly

К сожалению, нет прямого API для получения геометрического центра для трех видов полилиний. Кто-то может использовать топологические библиотеки, а кто-то предпочтет простейший из возможный способов – конвертирование AcDbPolyline, AcDb2Polyline, AcDb3dPolyline в область (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.    // Установим фильтр
  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.      }
  42.      ed.WriteMessage($ "\nГеометрический центр {pline.GetRXClass().DxfName}:{centroid}");
  43.     }
  44.     tr.Commit();
  45.    } else {
  46.     Autodesk.AutoCAD.ApplicationServices.Core.Application.ShowAlertDialog("Ничего не выбрано");
  47.    }
  48.  
  49.  
  50.   } catch (Autodesk.AutoCAD.Runtime.Exception ex) {
  51.    ed.WriteMessage(ex.ToString());
  52.   }
  53.  }
  54.  
  55.  
  56. }
  57.  
  58. public static void CenterMarkEntity(Point2d p) {
  59.   var doc = AcCoreApp.DocumentManager.MdiActiveDocument;
  60.   var db = doc.Database;
  61.   var ed = doc.Editor;
  62.   using(Transaction t = db.TransactionManager.StartTransaction()) {
  63.    short mode = (short) AcCoreApp.GetSystemVariable("PDMODE");
  64.    if (mode == 0) {
  65.     AcCoreApp.SetSystemVariable("PDMODE", 99);
  66.    }
  67.    var ms = t.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite) as BlockTableRecord;
  68.    DBPoint dbPt = new DBPoint(new Point3d(p.X, p.Y, .0)) {
  69.     ColorIndex = 3
  70.    };
  71.    ms.AppendEntity(dbPt);
  72.    t.AddNewlyCreatedDBObject(dbPt, true);
  73.    t.Commit();
  74.  
  75.   }
  76.  }

Тестовый чертеж: SampleDrawing

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

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