Вычитание регионов

Автор Тема: Вычитание регионов  (Прочитано 11804 раз)

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

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

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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Вычитание регионов
« : 18-06-2022, 19:02:22 »
Привет всем.
Подскажите не могу разобрать... вообщем есть два типа регионов которые создаются по полилинии (по слоям каждая группа в своем списке).
Потом создается третий список, который является "общим регионом" для двух списков (BoolIntersect), но данная опция не работает, а вот например объединение или вычитание работает на ура.
Так сразу скажу, пере вычитанием сперва создаю копию региона потом копию вычитаю, что бы список вычитаемого не менялся.
Может кто - подскажет...
Фаил исследования во вложении.

Код - C# [Выбрать]
  1.  
  2. namespace СomplicatedСonditions
  3.  
  4. {
  5.  
  6.     //Класс - поиска итоговых регионов
  7.     public class СomplicatedСonditionsRegion
  8.     {
  9.         #region Константы заполнения
  10.         //Константа пустота для строк
  11.         private const string Report = "Все землепользователи";
  12.         //Константа пустота для строк
  13.         private const string ReportEarth = "Землепользователи по земле";
  14.         //Константа единицы измерения
  15.         private const string UnitsMetrK = "м3";
  16.         //Константа
  17.         private const Char DelimitelPlus = '+';
  18.         //Константа делителя +
  19.         private const Char DelimitelMinus = '-';
  20.         //Константа делителя ПК
  21.         private const string PK = "ПК";
  22.  
  23.  
  24.         #endregion
  25.  
  26.         //Конструктор
  27.         public СomplicatedСonditionsRegion()
  28.         {
  29.         }
  30.  
  31.         //Копирование региона
  32.         private static void CopyRegion(out Region copyregion, Region localregion)
  33.         {
  34.             AcadDoc Draw = new AccessDoc();
  35.             Database db = Draw.DBase;
  36.             ObjectIdCollection collection = new ObjectIdCollection() { localregion.ObjectId };
  37.             // делаем Пространство Модели владельцем нового примитива
  38.             ObjectId ModelSpaceId = SymbolUtilityServices.GetBlockModelSpaceId(db);
  39.             IdMapping mapping = new IdMapping();
  40.             db.DeepCloneObjects(collection, ModelSpaceId, mapping, false);
  41.             using (Transaction tr = db.TransactionManager.StartTransaction())
  42.             {
  43.                 // получаем id-копии по id-оригинала
  44.                 IdPair pair1 = mapping[localregion.ObjectId];
  45.                 // открываем копию
  46.                 copyregion = tr.GetObject(pair1.Value, OpenMode.ForWrite) as Region;
  47.                 tr.Commit();
  48.             }
  49.         }
  50.  
  51.         //Создание списка регионов
  52.         static List<СomplicatedRegion> GetRegion(string nameLayer)
  53.         {
  54.             //экземпляр класса доступа к чертежу
  55.             AccessDoc AcToDraw = new AccessDoc();
  56.             Database db = AcToDraw.DBase;
  57.             Editor ae = AcToDraw.Ed;
  58.  
  59.             //выбор всех вхождений
  60.             TypedValue[] filterlist = new TypedValue[2];
  61.             filterlist.SetValue(new TypedValue((int)DxfCode.Start, "LWPOLYLINE"), 0);
  62.             filterlist.SetValue(new TypedValue((int)DxfCode.LayerName, nameLayer), 1);
  63.             SelectionFilter filter = new SelectionFilter(filterlist);
  64.             PromptSelectionResult acSSPrompt = ae.SelectAll(filter);
  65.             SelectionSet acSSet = acSSPrompt.Value;
  66.  
  67.             //Список регионов исследования
  68.             List<СomplicatedRegion> ListRegion = new List<СomplicatedRegion>();
  69.  
  70.             if (acSSPrompt.Status == PromptStatus.OK)
  71.             {
  72.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  73.                 {
  74.                     //BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  75.                     BlockTableRecord blocktableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  76.  
  77.                     foreach (SelectedObject selobj in acSSet)
  78.                     {
  79.  
  80.                         Polyline poly = tr.GetObject(selobj.ObjectId, OpenMode.ForRead) as Polyline;
  81.                         //Инициируем колекцию по полилинии
  82.                         DBObjectCollection acDBObjColl01 = new DBObjectCollection { poly };
  83.                         DBObjectCollection localRegion = Region.CreateFromCurves(acDBObjColl01);
  84.                         //Создаем регион по полилинии
  85.                         Region region = localRegion[0] as Region;
  86.                         //Добавляем регионы в чертеж
  87.                         blocktableRecord.AppendEntity(region);
  88.                         tr.AddNewlyCreatedDBObject(region, true);
  89.  
  90.                         ListRegion.Add(new СomplicatedRegion()
  91.                         {
  92.                             //Id региона      
  93.                             Id = region.ObjectId,
  94.                             //Имя региона        
  95.                             NameRegion = nameLayer,
  96.                             //Тип региона      
  97.                             TypeRegion = nameLayer,
  98.                             //ПК начала региона      
  99.                             BeginPK = "00+00",
  100.                             //ПК начала региона      
  101.                             EndPK = "00+00",
  102.                             //КМ начала региона    
  103.                             BeginKM = 12.1,
  104.                             //КМ начала региона    
  105.                             EndKM = 12.1,
  106.                             //Площадь      
  107.                             Square = region.Area,
  108.                             //Слой объекта      
  109.                             RegionLayer = nameLayer
  110.                         });
  111.                     }
  112.                     tr.Commit();
  113.                 }
  114.             }
  115.             else
  116.             {
  117.                 MessageBox.Show("Нет характерных зон");
  118.             }
  119.             return ListRegion;
  120.         }
  121.  
  122.         //Создание списка регионов совместных зон
  123.         static List<СomplicatedRegion> GetRegionСС_OZ()
  124.         {
  125.             //Список регионов - стесненность
  126.             List<СomplicatedRegion> RegionСС = GetRegion(WorkLayer.layerСС);
  127.             //MessageBox.Show("RegionСС = " + RegionСС.Count().ToString());
  128.             //Список регионов - ОЗ ВЛ
  129.             List<СomplicatedRegion> RegionOZ = GetRegion(WorkLayer.layerOZ);
  130.             //MessageBox.Show("RegionOZ = " + RegionOZ.Count().ToString());
  131.  
  132.             //Список регионов исследования
  133.             List<СomplicatedRegion> RegionСС_OZ = new List<СomplicatedRegion>();
  134.  
  135.             //экземпляр класса доступа к чертежу
  136.             AccessDoc AcToDraw = new AccessDoc();
  137.             Database db = AcToDraw.DBase;
  138.  
  139.             using (Transaction tr = db.TransactionManager.StartTransaction())
  140.             {
  141.                 BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
  142.                 BlockTableRecord blocktableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  143.  
  144.                 foreach (СomplicatedRegion regionСС in RegionСС)
  145.                 {
  146.                     //выбираем регионы по стеснености
  147.                     Region region_CC = tr.GetObject(regionСС.Id, OpenMode.ForWrite) as Region;
  148.                     //Плошадь для сравнения изменений
  149.                     double area01 = region_CC.Area;
  150.                     //Создаем копию изменяемого региона
  151.                     //CopyRegion(out Region copyregion01, region_CC);
  152.                     //Сортировка - поиск обединенных регионов
  153.                     foreach (СomplicatedRegion regionOZ in RegionOZ)
  154.                     {
  155.                         //Создаем копию изменяемого региона
  156.                         CopyRegion(out Region copyregion02, tr.GetObject(regionOZ.Id, OpenMode.ForWrite) as Region);
  157.                         //Поиск общего пересечения
  158.                         region_CC.BooleanOperation(BooleanOperationType.BoolIntersect, copyregion02);
  159.                     }
  160.                     //площадь пересечения
  161.                     double area02 = region_CC.Area;
  162.                     //Запись нового объекта в новый список
  163.                     if (area01 != area02)
  164.                     {
  165.                         //Region newregion = tr.GetObject(copyregion01.Id, OpenMode.ForWrite) as Region;
  166.  
  167.                         //blocktableRecord.AppendEntity(newregion);
  168.                         //tr.AddNewlyCreatedDBObject(newregion, true);
  169.  
  170.                         RegionСС_OZ.Add(new СomplicatedRegion()
  171.                         {
  172.                             //Id региона      
  173.                             Id = copyregion01.ObjectId,
  174.                             //Имя региона        
  175.                             NameRegion = WorkLayer.layerССandOZ,
  176.                             //Тип региона      
  177.                             TypeRegion = WorkLayer.layerССandOZ,
  178.                             //ПК начала региона      
  179.                             BeginPK = "00+00",
  180.                             //ПК начала региона      
  181.                             EndPK = "00+00",
  182.                             //КМ начала региона    
  183.                             BeginKM = 12.1,
  184.                             //КМ начала региона    
  185.                             EndKM = 12.1,
  186.                             //Площадь      
  187.                             Square = copyregion01.Area,
  188.                             //Слой объекта      
  189.                             RegionLayer = WorkLayer.layerССandOZ
  190.                         });
  191.                     }
  192.  
  193.  
  194.  
  195.  
  196.                 }
  197.                 tr.Commit();
  198.             }
  199.             MessageBox.Show("RegionСС_OZ = " + RegionСС_OZ.Count().ToString());
  200.             return RegionСС_OZ;
  201.         }
  202.  
  203.  
  204.  
  205.  
  206.         [CommandMethod("СomplicatedRegion")]
  207.         public void СomplicatedRegion()
  208.         {
  209.             List<СomplicatedRegion> RegionCC_ZZ = GetRegionСС_OZ();
  210.  
  211.  
  212.         }
  213.  
  214.     }
  215. }
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Вычитание регионов
« Ответ #1 : 18-06-2022, 19:05:54 »
Код весь не смотрел, но метод CopyRegion работать не будет. Нельзя использовать объект, открытый в транзакции, после ее завершения.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Re: Вычитание регионов
« Ответ #2 : 18-06-2022, 19:11:41 »
Т.е. после копирования надо получать прямую ссылку на новый объект.
Копирвоание должно создавать объект, а возвращать ID  нового объекта?

Отмечено как Решение Judas 19-06-2022, 10:43:40

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Вычитание регионов
« Ответ #3 : 18-06-2022, 19:13:48 »
Копирвоание должно создавать объект, а возвращать ID  нового объекта?
Не знаю. Это зависит от логики твоей программы. Я лишь нашел узкое место в твоей программе.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Re: Вычитание регионов
« Ответ #4 : 18-06-2022, 19:14:46 »
хорошо, по тестю.
Пока не буду писать про решение.

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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Re: Вычитание регионов
« Ответ #5 : 18-06-2022, 19:28:25 »
Это принципиально...
Вычитание работает как надо - а пересечение нет.
Код - C# [Выбрать]
  1.                     foreach (СomplicatedRegion regionOZ in RegionOZ)
  2.                     {
  3.                         //Создаем копию изменяемого региона
  4.                         CopyRegion(out ObjectId idRegion, tr.GetObject(regionOZ.Id, OpenMode.ForWrite) as Region);
  5.                         Region r = tr.GetObject(idRegion, OpenMode.ForWrite) as Region;
  6.                         //Добавляем регионы в чертеж
  7.  
  8.                         //Поиск общего пересечения
  9.                         //region_CC.BooleanOperation(BooleanOperationType.BoolIntersect, r);
  10.                         region_CC.BooleanOperation(BooleanOperationType.BoolSubtract, r);
  11.                     }


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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Re: Вычитание регионов
« Ответ #6 : 18-06-2022, 19:37:09 »
А если потеснить на простых фигурах - два квадрата - все работает.
Может это из сложности фигур или точек, хотя в ручную все робит норм.


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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Вычитание регионов
« Ответ #7 : 18-06-2022, 19:42:25 »
Judas,
Ну например может не работать, если большие координаты (если это геодезические координаты, то точно работать не будет). И точность работы с Region порядка 1e-6.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Re: Вычитание регионов
« Ответ #8 : 18-06-2022, 19:46:49 »
Координаты большие. но обычные шестизначные X,Y.
(для пересадки с исходниках)
Но странное, если это делать пересечение средствами автокад все работает.
Точность 1е-6 не нужно, достаточно до 0,1.

Причем такая штука: если после удалить в ручную все области, то в выборе еще есть области которые непоказываются!

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Вычитание регионов
« Ответ #9 : 18-06-2022, 19:50:11 »
Координаты большие. но обычные шестизначные X,Y.
Это слишком много.
Точность 1е-6 не нужно, достаточно до 0,1.
Точность в данном случае это не количество знаков после запятой, а количество значащих цифр.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Вычитание регионов
« Ответ #10 : 18-06-2022, 19:54:49 »
Кстати, а ты пробовал использовать метод Clone для создания клона Region перед Intersect? В документации используется метод Clone, хотя я не проверял работоспособность этого метода в данном случае.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Re: Вычитание регионов
« Ответ #11 : 18-06-2022, 20:05:47 »
Я использую db.DeepCloneObjects(collection, ModelSpaceId, mapping, false);

После отработки метода исходные регионы ранее созданные отрисовываются как надо и их видно.
Их общее количества 3 для примера, а если использовать быстрый выбор, и выбрать области то их 5.



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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Вычитание регионов
« Ответ #12 : 18-06-2022, 20:07:33 »
Все равно он создает пересечение но не отражает, странно...
Переведи на русский...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Re: Вычитание регионов
« Ответ #13 : 18-06-2022, 20:12:26 »
Я использую db.DeepCloneObjects(collection, ModelSpaceId, mapping, false);

После отработки метода исходные регионы ранее созданные отрисовываются как надо и их видно.
Их общее количества 3 для примера, а если использовать быстрый выбор, и выбрать области то их 5.

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

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Re: Вычитание регионов
« Ответ #14 : 18-06-2022, 20:15:36 »
r1.BooleanOperation(BooleanOperationType.BoolUnite, r2); - работает.
r1.BooleanOperation(BooleanOperationType.BoolSubtract, r2); - работает.
r1.BooleanOperation(BooleanOperationType.BoolIntersect, r2); - НЕ работает.