Извлечение координат вершин полилинии в коллекцию

Автор Тема: Извлечение координат вершин полилинии в коллекцию  (Прочитано 9249 раз)

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Здравствуйте!
Пишу код для установки координат полилинии без дробных частей. Очень больная проблема при работе с контрагентскими чертежами - очень часто чертят без привязок, на глаз.
Ловлю Fatal error при входе в метод VerticesToCollection. В чем я неправ?

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Geometry;
  5. using Autodesk.AutoCAD.Runtime;
  6. using System;
  7.  
  8. namespace ITAT_Autocad
  9. {
  10.     internal class CoordinatesNormalizer
  11.     {
  12.         public static double RoundOff(double input, int accuracy)
  13.         {
  14.             double result;
  15.             result = Math.Abs(input / accuracy) * accuracy;
  16.             return result;
  17.         }
  18.  
  19.         public static Point2dCollection NormalizePoint(Point2dCollection vertices)
  20.         {
  21.             Point2dCollection normVertices = null;
  22.             foreach (Point2d vertice in vertices)
  23.             {
  24.                 Point2d normVertice = new Point2d(RoundOff(vertice.X, 5), RoundOff(vertice.Y, 5));
  25.                 normVertices.Add(normVertice);
  26.             }
  27.  
  28.             return normVertices;
  29.         }
  30.         public static Point2dCollection VerticesToCollection(Polyline polyline)
  31.         {
  32.             Point2dCollection vertices = null;
  33.             for (int i = 0; i < polyline.NumberOfVertices; i++)
  34.             {
  35.                 vertices.Add(polyline.GetPoint2dAt(i));
  36.             }
  37.  
  38.             return vertices;
  39.         }
  40.     }
  41.  
  42.  
  43.     public static class Linesnormalizer
  44.     {
  45.         [CommandMethod("0RoundOff", CommandFlags.Modal)]
  46.         public static void RoundOffPoints()
  47.         {
  48.             Document doc = Application.DocumentManager.MdiActiveDocument;
  49.             Database db = doc.Database;
  50.             Editor ed = doc.Editor;
  51.             using (Transaction tr = db.TransactionManager.StartTransaction())
  52.             {
  53.                 Point2dCollection point2DCollection=null;
  54.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
  55.                 foreach (ObjectId btrId in bt)
  56.                 {
  57.                     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite);
  58.                     if (btr.IsFromExternalReference)
  59.                     {
  60.                         continue;
  61.                     }
  62.  
  63.                     foreach (ObjectId id in btr)
  64.                     {
  65.                         Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);
  66.                         if (ent is Polyline)
  67.                         {
  68.                             Polyline pline = (Polyline)ent;
  69.                             point2DCollection = CoordinatesNormalizer.VerticesToCollection(pline);
  70.                             var normVertices = CoordinatesNormalizer.NormalizePoint(point2DCollection);
  71.                             for (int i = 0; i < normVertices.Count; i++)
  72.                             {
  73.                                 pline.AddVertexAt(i, normVertices[i], 0, 0, 0);
  74.                             }
  75.  
  76.                         }
  77.  
  78.                         if (ent is Line)
  79.                         {
  80.                             continue;
  81.                         }
  82.                     }
  83.                 }
  84.  
  85.                 tr.Commit();
  86.             }
  87.  
  88.             ed.Regen();
  89.         }
  90.     }
  91. }

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Внимательно смотрим на строку 32.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Дмитрий Загорулькин,
И сразу на строку 21.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Atomohod,
В коде очень много откровенной ерунды. Например:
1) зачем открывать BlockTable для записи?
2) зачем открывать BlockTableRecord для записи?
3) ты зачем-то добавляешь вершины к полилинии используя метод AddVertexAt вместо замены их методом SetPointAt
and so on...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
1) зачем открывать BlockTable для записи?
2) зачем открывать BlockTableRecord для записи?
Согласен, это я изменил с ForRead пытаясь побороть FatalError. Не помогло.

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Внимательно смотрим на строку 32.
Похоже я туплю, но все же. Почему объявление переменной для сохранения точек не верно?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Внимательно смотрим на строку 32.
Похоже я туплю, но все же. Почему объявление переменной для сохранения точек не верно?
Подумай что такое null.Add ?
Должно быть:
Код - C# [Выбрать]
  1. Point2dCollection vertices = new Point2dCollection();

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
А Функция Math.Abs() в  RoundOff никого не смутила (строка 15)?  :o

ИМХО, автор очень сильно перемудрил...
Код - C# [Выбрать]
  1.         [Rtm.CommandMethod("0RoundOff")]
  2.         static public void RoundOffPoints()
  3.         {
  4.             App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
  5.             if (acDoc == null) return;
  6.             Db.Database acCurDb = acDoc.Database;
  7.             Ed.Editor acEd = acDoc.Editor;
  8.             int accuracy = 5;
  9.             using (Db.BlockTableRecord btr = acCurDb.CurrentSpaceId.Open(Db.OpenMode.ForRead) as Db.BlockTableRecord)
  10.             {
  11.                 foreach (Db.ObjectId id in btr)
  12.                 {
  13.                     if (id.ObjectClass.IsDerivedFrom(Rtm.RXClass.GetClass(typeof(Db.Polyline))))
  14.                     {
  15.                         using (Db.Polyline pl = id.Open(Db.OpenMode.ForWrite) as Db.Polyline)
  16.                         {
  17.                             for (int i =0; i < pl.NumberOfVertices; i++)
  18.                                 pl.SetPointAt(i, Round(pl.GetPoint2dAt(i), accuracy));
  19.                         }
  20.                     }
  21.                 }
  22.             }
  23.         }
  24.         public static Gem.Point2d Round(Gem.Point2d point, int accuracy)
  25.         {
  26.             Gem.Point2d result;
  27.             result = new Gem.Point2d (
  28.                 Math.Round(point.X / accuracy) * accuracy,
  29.                 Math.Round(point.Y / accuracy) * accuracy
  30.                 );
  31.             return result;
  32.         }

Справедливости ради замечу, что приведенный выше код мне не нравиться, т.к. он не учитывает например другую систему координат, расположение детали и пр.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
А Функция Math.Abs() в  RoundOff никого не смутила (строка 15)? 
Ну это уже ошибка логическая :)
Мы же смотрели пока только на ошибки времени выполнения.