Подрезка блока

Автор Тема: Подрезка блока  (Прочитано 3024 раз)

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

Оффлайн Леонид СеменовАвтор темы

  • ADN Club
  • Сообщений: 44
  • Карма: 2
  • Леонид Семенов. Ведущий инженер-программист
Подрезка блока
« : 27-06-2016, 14:20:28 »
Здравствуйте.
Мне нужно подрезать блок прямоугольником, скажите пожалуйста, как это выполнить.
Думаю, что нужно применить SetClipBoundary(), но как его использовать для блоков не нашел ничего.

Отмечено как Решение Леонид Семенов 28-06-2016, 09:49:26

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Подрезка блока
« Ответ #1 : 27-06-2016, 16:09:38 »
На основе вот этого кода: http://through-the-interface.typepad.com/through_the_interface/2010/11/adding-a-2d-spatial-filter-to-perform-a-simple-xclip-on-an-external-reference-in-autocad-using-net.html я сделал более универсальный (с произвольным контуром подрезки - в том примере подрезка идёт прямоугольником):

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.DatabaseServices;
  2. using Autodesk.AutoCAD.EditorInput;
  3. using Autodesk.AutoCAD.Geometry;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices.Filters;
  6. using Autodesk.AutoCAD.Runtime;
  7. using System;
  8.  
  9.  
  10. namespace SpatialFiltering
  11. {
  12.   public class ClipBlock
  13.   {
  14.     const string filterDictName = "ACAD_FILTER";
  15.     const string spatialName = "SPATIAL";
  16.  
  17.     [CommandMethod("XCLIPBREF")]
  18.     public static void clipBlockTest()
  19.     {
  20.       Document doc = Application.DocumentManager.MdiActiveDocument;
  21.       Database db = doc.Database;
  22.       Editor ed = doc.Editor;
  23.  
  24.       // Выбираем блок для подрезки
  25.  
  26.       PromptEntityOptions peo =  
  27.         new PromptEntityOptions("\nВыберите вставку блока:");
  28.       peo.AllowNone = false;
  29.       peo.SetRejectMessage("\nЭто не вставка блока.");
  30.       peo.AddAllowedClass(typeof(BlockReference), false);
  31.  
  32.       PromptEntityResult per = ed.GetEntity(peo);
  33.  
  34.       if (per.Status != PromptStatus.OK)
  35.         return;
  36.       Point3dCollection pts3d = new Point3dCollection();
  37.  
  38.       // Выбираем точки для подрезки
  39.       while (true)
  40.       {
  41.         PromptPointOptions ppo;
  42.         if (pts3d.Count < 3) {
  43.           ppo = new PromptPointOptions("\nУкажите " + (pts3d.Count + 1).ToString() + "-ую точку контура");
  44.           ppo.AllowNone = false;
  45.         }  else  {
  46.           ppo = new PromptPointOptions("\nУкажите " + (pts3d.Count + 1).ToString() + "-ую точку контура (ENTER - завершение)");
  47.           ppo.AllowNone = true;
  48.         }
  49.  
  50.         if (pts3d.Count > 0)
  51.         {
  52.           ppo.BasePoint = pts3d[pts3d.Count-1];
  53.           ppo.UseBasePoint = true;
  54.         }
  55.  
  56.         PromptPointResult ppr = ed.GetPoint(ppo);
  57.  
  58.         if (ppr.Status != PromptStatus.OK)
  59.           break;
  60.  
  61.         if (pts3d.Count > 0)
  62.           ed.DrawVector(pts3d[pts3d.Count - 1], ppr.Value, 1, true);
  63.  
  64.         pts3d.Add(ppr.Value);
  65.       }
  66.  
  67.       Transaction tr = db.TransactionManager.StartTransaction();
  68.  
  69.       using (tr)
  70.       {
  71.         // Преобразуем точки в систему координат блока!!!
  72.         BlockReference br =  (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForRead);
  73.         Point2dCollection pts = new Point2dCollection(pts3d.Count);
  74.         Matrix3d mat = br.BlockTransform.Inverse();
  75.         foreach (Point3d p in pts3d)
  76.         {
  77.           Point3d pBlk  = p.TransformBy(mat);
  78.           pts.Add(new Point2d(pBlk.X, pBlk.Y));
  79.         }
  80.  
  81.  
  82.         // Создаем фильтр
  83.  
  84.         SpatialFilterDefinition sfd =
  85.           new SpatialFilterDefinition(
  86.             pts, Vector3d.ZAxis, 0.0, 0.0, 0.0, true
  87.           );
  88.  
  89.         SpatialFilter sf = new SpatialFilter();
  90.  
  91.         sf.Definition = sfd;
  92.  
  93.         // Создаем ExtDict если его еще не было
  94.  
  95.         if (br.ExtensionDictionary == ObjectId.Null)
  96.         {
  97.           br.UpgradeOpen();
  98.           br.CreateExtensionDictionary();
  99.           br.DowngradeOpen();
  100.         }
  101.  
  102.         // Добавляем фильтр
  103.  
  104.         DBDictionary xDict = (DBDictionary)tr.GetObject(br.ExtensionDictionary, OpenMode.ForWrite);
  105.  
  106.         if (xDict.Contains(filterDictName))
  107.         {
  108.           DBDictionary fDict =
  109.             (DBDictionary)tr.GetObject(
  110.               xDict.GetAt(filterDictName), OpenMode.ForWrite
  111.             );
  112.           if (fDict.Contains(spatialName))
  113.             fDict.Remove(spatialName);
  114.           fDict.SetAt(spatialName, sf);
  115.         }
  116.         else
  117.         {
  118.           DBDictionary fDict = new DBDictionary();
  119.           xDict.SetAt(filterDictName, fDict);
  120.           tr.AddNewlyCreatedDBObject(fDict, true);
  121.           fDict.SetAt(spatialName, sf);
  122.         }
  123.  
  124.         tr.AddNewlyCreatedDBObject(sf, true);
  125.         tr.Commit();
  126.       }
  127.       ed.Regen();
  128.     }
  129.   }
  130. }


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

Оффлайн Леонид СеменовАвтор темы

  • ADN Club
  • Сообщений: 44
  • Карма: 2
  • Леонид Семенов. Ведущий инженер-программист
Re: Подрезка блока
« Ответ #2 : 28-06-2016, 09:50:52 »
Спасибо большое.