Как отфильтровать геометрию в составе blockReference и вне его?

Автор Тема: Как отфильтровать геометрию в составе blockReference и вне его?  (Прочитано 7797 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн AtomohodАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Здравствуйте!
Столкнулся с такой проблемой - правлю координаты контрагентской документации, округляю размеры и положения объектов например 179,58933969 привожу к 180.00. Обрабатываю полилинии и blockReference. У первых округляю вершины, у блоков точку вставки. Обнаружил неприятный побочный эффект при обработке полилиний вершины округляются у геометрии внутри блоков, а этого делать не следует.
Вопрос - как выделить геометрию внутри блока и исключить ее из обработки? Ищу что-то вроде свойства, которое показывает находится геометрия внутри блока или нет.

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Это ж каким-таким способом вы полилинии получаете? Те что из пространства модели или бумаги получены - те обрабатывайте, а те что из других BTR - не обрабатывайте.

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Свойство BlockName проверьте

Оффлайн AtomohodАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Это ж каким-таким способом вы полилинии получаете?
Вот мой код
Код - C# [Выбрать]
  1.  public static void RoundOffPoints()
  2.         {
  3.             Document doc = Application.DocumentManager.MdiActiveDocument;
  4.             Database db = doc.Database;
  5.             Editor ed = doc.Editor;
  6.             double accuracy = SelectionUtilities.GetNumParameter("Set desired accuracy");
  7.             using (Transaction tr = db.TransactionManager.StartTransaction())
  8.             {
  9.                 Point2dCollection point2DCollection = null;
  10.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
  11.                 foreach (ObjectId btrId in bt)
  12.                 {
  13.                     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite);
  14.                     if (btr.IsFromExternalReference)
  15.                     {
  16.                         continue;
  17.                     }
  18.  
  19.                     foreach (ObjectId id in btr)
  20.                     {
  21.                         Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite, false, true);
  22.                         if (ent is Polyline)
  23.                         {
  24.                             Polyline pline = (Polyline)ent;
  25.                             point2DCollection = CoordinatesNormalizer.VerticesToCollection(pline);
  26.  
  27.                             Point2dCollection normVertices = CoordinatesNormalizer.NormalizePoint(accuracy, point2DCollection);
  28.                             for (int i = 0; i < normVertices.Count; i++)
  29.                             {
  30.                                 pline.SetPointAt(i, normVertices[i]);
  31.                             }
  32.                         }
  33.  
  34.                         if (ent is Line)
  35.                         {
  36.                             Line line = (Line)ent;
  37.                             point2DCollection = CoordinatesNormalizer.VerticesToCollection(line);
  38.                             Point2dCollection normVertices = CoordinatesNormalizer.NormalizePoint(accuracy, point2DCollection);
  39.                             line.StartPoint = new Point3d(normVertices[0].X, normVertices[0].Y, 0);
  40.                             line.EndPoint = new Point3d(normVertices[1].X, normVertices[1].Y, 0);
  41.  
  42.                         }
  43.                         if (ent is BlockReference)
  44.                         {
  45.                             BlockReference bref = (BlockReference)ent;
  46.                            
  47.                             Point3d newPoint3D = CoordinatesNormalizer.NormalizePoint(accuracy,bref.Position);
  48.                             Matrix3d displacement = Matrix3d.Displacement(new Vector3d(newPoint3D.X-bref.Position.X, newPoint3D.Y - bref.Position.Y, 0));
  49.  
  50.                             bref.TransformBy(displacement);
  51.                         }
  52.                     }
  53.                 }
  54.  
  55.                 tr.Commit();
  56.             }
  57.  
  58.             ed.Regen();
  59.         }

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Понятно. Т.е. вы вполне умышленно редактируете все содержимое всех блоков без разбора, а потом удивляетесь, что оно отредактировано :) Если вам нужны объекты из модели, то берите их только из btr.Name == "*Model_Space", а на листах btr.Name.StartsWith("*Paper_Space"). А если листы не нужны, то и вовсе незачем перебирать всю таблицу блоков. Берите модель сразу
Код - C# [Выбрать]
  1. BlockTableRecord model = tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite) as BlockTableRecord

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
И просто для информации - в последнем c# можно записывать вместо
Код - C# [Выбрать]
  1.                         if (ent is Line)
  2.                         {
  3.                             Line line = (Line)ent;
можно объявить новую переменную line сразу в операторе is
Код - C# [Выбрать]
  1.                         if (ent is Line line)
  2.                         {

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Atomohod,
Как я понимаю лезть во все блоки не нужно. Нужно лезть в пространство модели и (возможно) листы. В этом случае достаточно проверки
Код - C# [Выбрать]
  1. if (btr.IsLayout) {
  2. // Это пространство модели или одного из листов.
  3. // Имеет смысл "править координаты" только в этом случае
  4. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн AtomohodАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Как я понимаю лезть во все блоки не нужно. Нужно лезть в пространство модели и (возможно) листы. В этом случае достаточно проверки
Чуть похитрее - в пространстве модели есть и блоки оборудования, внутри которых ничего округлять нельзя и обычные полилинии, которыми выполнен чертеж. В пространстве листа ничего не оформлено и так  - там совсем пусто. У блоков нужно только округлить точку вставки т.к. их похоже, что привязывали навскидку.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Как я понимаю лезть во все блоки не нужно. Нужно лезть в пространство модели и (возможно) листы. В этом случае достаточно проверки
Чуть похитрее - в пространстве модели есть и блоки оборудования, внутри которых ничего округлять нельзя и обычные полилинии, которыми выполнен чертеж. В пространстве листа ничего не оформлено и так  - там совсем пусто. У блоков нужно только округлить точку вставки т.к. их похоже, что привязывали навскидку.
Ну тогда мой предложенные мной и avc  варианты должны работать. Ничего хитрого я не вижу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Atomohod 21-07-2019, 17:33:00

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Вот смотрю я на эту цитату:
в пространстве модели есть и блоки оборудования, внутри которых ничего округлять нельзя и обычные полилинии, которыми выполнен чертеж. В пространстве листа ничего не оформлено и так  - там совсем пусто. У блоков нужно только округлить точку вставки т.к. их похоже, что привязывали навскидку.

а потом еще раз на код автора: ссылка
Вижу, что код делает совсем не то, что нужно автору появляется много вопросов...

В моем понимание, "У блоков нужно только округлить точку вставки", выглядит как то так:
Код - C# [Выбрать]
  1.         static public void RoundOffPointBlockReference()
  2.         {
  3.             App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
  4.             if (acDoc == null) return;
  5.             Db.Database acCurDb = acDoc.Database;
  6.             Ed.Editor acEd = acDoc.Editor;
  7.  
  8.             double accuracy = SelectionUtilities.GetNumParameter("Set desired accuracy");
  9.  
  10.             Db.ObjectId ModelSpaceId = Db.SymbolUtilityServices.GetBlockModelSpaceId(acCurDb);
  11.             using (Db.BlockTableRecord btr = ModelSpaceId.Open(Db.OpenMode.ForRead) as Db.BlockTableRecord)
  12.             {
  13.                 foreach(Db.ObjectId id in btr)
  14.                 {
  15.                     if (id.ObjectClass.IsDerivedFrom(Rtm.RXObject.GetClass(typeof(Db.BlockReference))))
  16.                     {
  17.                         using(Db.BlockReference bref = id.Open(Db.OpenMode.ForWrite)as Db.BlockReference)
  18.                         {
  19.                             Gem.Point3d newPoint3D = CoordinatesNormalizer.NormalizePoint(accuracy, bref.Position);
  20.                             Gem.Matrix3d displacement = Gem.Matrix3d.Displacement(bref.Position.GetVectorTo(newPoint3D));
  21.                             bref.TransformBy(displacement);
  22.                         }
  23.                     }
  24.                 }
  25.             }
  26.         }