отображение ручек при создании подрезки XRef

Автор Тема: отображение ручек при создании подрезки XRef  (Прочитано 8598 раз)

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

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

Оффлайн Владимир ШуАвтор темы

  • ADN Club
  • *****
  • Сообщений: 626
  • Карма: 161
    • ПГСу Бложик
День добрый.

На просторах knowledge.autodesk.com нашел код (метод), который позволяет подрезать внешнюю ссылку, блок и т.п. Создаем фильтр и добавляем его в словарь расширенных данных объекта... вот набор ссылок:
1) http://help.autodesk.com/cloudhelp/2016/ENU/AutoCAD-NET/files/GUID-72029044-0840-4187-9A58-F2A4518E3A23.htm
2) https://www.keanw.com/2010/11/adding-a-2d-spatial-filter-to-perform-a-simple-xclip-on-an-external-reference-in-autocad-using-net.html
3) https://knowledge.autodesk.com/ru/search-result/caas/CloudHelp/cloudhelp/2016/RUS/AutoCAD-NET/files/GUID-72029044-0840-4187-9A58-F2A4518E3A23-htm.html
4) https://adndevblog.typepad.com/autocad/2013/01/spatial-filter-xclip-command-command-in-c.html (тут по сути то же самое, создается фильтр и добавляется в словарь...)
5) http://autolisp.ru/2011/11/30/create-xclip/ и тат приблизительно то же самое
Код отрабатывает правильно, но... проблема в том, что у созданной подрезки не отображаются ручки (grips) и единственный способ их увидеть - сохранить файл, закрыть и заново открыть.

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

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Владимир Шу,
Давай точный тестовый код, которым ты создаёшь подрезку - потестирую. Ну и укажи версию AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир ШуАвтор темы

  • ADN Club
  • *****
  • Сообщений: 626
  • Карма: 161
    • ПГСу Бложик
Да код то в базовой части почти не отличается от примеров... Autocad 2017x64
Код выдирал с мясом из проекта, возможно что то не подчистил, но работает он так же как описано выше
Код - C# [Выбрать]
  1. using System.Collections.Generic;
  2. using App = Autodesk.AutoCAD.ApplicationServices;
  3. using Db = Autodesk.AutoCAD.DatabaseServices;
  4. using Ed = Autodesk.AutoCAD.EditorInput;
  5. using Gem = Autodesk.AutoCAD.Geometry;
  6. using Rtm = Autodesk.AutoCAD.Runtime;
  7. [assembly: Rtm.CommandClass(typeof(ClipedXref.Test))]
  8. namespace ClipedXref
  9. {
  10.   class Test
  11.   {
  12.     private static double XRefWidth { get; set; } = 10;
  13.     const string filterDictName = "ACAD_FILTER";
  14.     const string spatialName = "SPATIAL";
  15.  
  16.     [Rtm.CommandMethod("zz")]
  17.     public static void ClipedXref()
  18.     {
  19.       App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
  20.       if (acDoc == null) return;
  21.       Db.Database acCurDb = acDoc.Database;
  22.       Ed.Editor acEd = acDoc.Editor;
  23.  
  24.       using (Db.Transaction tr = acCurDb.TransactionManager.StartTransaction())
  25.       {
  26.         Ed.PromptEntityOptions opt = new Ed.PromptEntityOptions($"\n\nSelect line in XRef:");
  27.         opt.AllowNone = false;
  28.         opt.AllowObjectOnLockedLayer = true;
  29.         opt.SetRejectMessage("\nYou must select XRef!");
  30.         opt.AddAllowedClass(typeof(Db.BlockReference), true);
  31.  
  32.         Ed.PromptEntityResult res = acEd.GetEntity(opt);
  33.         if (res.Status != Ed.PromptStatus.OK) return;
  34.  
  35.         Db.BlockReference cloneXref = null;
  36.         List<Gem.Point3d> ptsIn = new List<Gem.Point3d>();
  37.  
  38.         if (res.ObjectId.ObjectClass.IsDerivedFrom(Rtm.RXClass.GetClass(typeof(Db.BlockReference))))
  39.         {
  40.           Db.BlockReference br = tr.GetObject(res.ObjectId, Db.OpenMode.ForRead) as Db.BlockReference;
  41.           if (br != null)
  42.           {
  43.             Db.ObjectId btrId = br.BlockTableRecord;
  44.             Db.BlockTableRecord btr = tr.GetObject(btrId, Db.OpenMode.ForRead) as Db.BlockTableRecord;
  45.             if (btr != null)
  46.             {
  47.               if (btr.IsFromExternalReference)
  48.               {
  49.                 Ed.PromptNestedEntityOptions pneo = new Ed.PromptNestedEntityOptions("");
  50.                 pneo.NonInteractivePickPoint = res.PickedPoint;
  51.                 pneo.UseNonInteractivePickPoint = true;
  52.                 Ed.PromptNestedEntityResult pner = acEd.GetNestedEntity(pneo);
  53.  
  54.                 if (pner.Status == Ed.PromptStatus.OK)
  55.                 {
  56.                   Db.ObjectId selId = pner.ObjectId;
  57.                   if (selId.ObjectClass.IsDerivedFrom(Rtm.RXClass.GetClass(typeof(Db.Line))))
  58.                   {
  59.                     cloneXref = br.Clone() as Db.BlockReference;
  60.                     using (Db.Line line = selId.Open(Db.OpenMode.ForRead) as Db.Line)
  61.                     {
  62.                       ptsIn.Add(line.StartPoint);
  63.                       ptsIn.Add(line.EndPoint);
  64.                     }
  65.                   }
  66.                 }
  67.               }
  68.             }
  69.           }
  70.         }
  71.  
  72.         if (cloneXref != null && ptsIn.Count > 0)
  73.         {
  74.           Ed.PromptPointOptions optPnt = new Ed.PromptPointOptions("\nPick a point to insert XRef: ");
  75.           optPnt.AllowNone = false;
  76.           Ed.PromptPointResult resPnt = acEd.GetPoint(optPnt);
  77.           if (resPnt.Status == Ed.PromptStatus.OK)
  78.           {
  79.             Gem.Matrix3d mat = cloneXref.BlockTransform;
  80.             Gem.Vector3d v1 = ptsIn[0].TransformBy(mat).GetVectorTo(resPnt.Value);
  81.             for (int i = 0; i < ptsIn.Count; i++)
  82.               ptsIn[i] = ptsIn[i].TransformBy(mat) + v1;
  83.  
  84.             CreateEXref(tr, acCurDb.CurrentSpaceId, cloneXref, ptsIn, XRefWidth, v1);
  85.           }
  86.         }
  87.         tr.Commit();
  88.       }
  89.       acEd.Regen();
  90.     }
  91.  
  92.  
  93.     private static void CreateEXref(Db.Transaction tr, Db.ObjectId CurrentSpaceId, Db.BlockReference cloneXrefIn, List<Gem.Point3d> ptsIn, double dist, Gem.Vector3d v1)
  94.     {
  95.  
  96.       Db.BlockTableRecord acBlkTblRec = tr.GetObject(CurrentSpaceId, Db.OpenMode.ForWrite) as Db.BlockTableRecord;
  97.       for (int i = 0; i < ptsIn.Count - 1; i++)
  98.       {
  99.         Db.BlockReference cloneXref = cloneXrefIn.Clone() as Db.BlockReference;
  100.         cloneXref.TransformBy(Gem.Matrix3d.Displacement(v1));
  101.  
  102.         acBlkTblRec.AppendEntity(cloneXref);
  103.         tr.AddNewlyCreatedDBObject(cloneXref, true);
  104.  
  105.         Gem.Point3dCollection pts3d = new Gem.Point3dCollection();
  106.         Gem.Vector3d vG = ptsIn[i].GetVectorTo(ptsIn[i + 1]);
  107.         Gem.Vector3d vV = vG.GetPerpendicularVector().GetNormal() * dist / 2;
  108.  
  109.         pts3d.Add(ptsIn[i] + vV);
  110.         pts3d.Add(ptsIn[i] + vG + vV);
  111.         pts3d.Add(ptsIn[i] + vG - vV);
  112.         pts3d.Add(ptsIn[i] - vV);
  113.  
  114.         Gem.Point2dCollection pts = new Gem.Point2dCollection(pts3d.Count);
  115.         Gem.Matrix3d mat = cloneXref.BlockTransform.Inverse();
  116.         foreach (Gem.Point3d p in pts3d)
  117.         {
  118.           Gem.Point3d pBlk = p.TransformBy(mat);
  119.           pts.Add(new Gem.Point2d(pBlk.X, pBlk.Y));
  120.         }
  121.  
  122.         using (Db.Filters.SpatialFilter sf = new Db.Filters.SpatialFilter())
  123.         {
  124.           Db.Filters.SpatialFilterDefinition sfd = new Db.Filters.SpatialFilterDefinition(pts, Gem.Vector3d.ZAxis, 0.0, 1e7, -1e7, true);
  125.           sf.Definition = sfd;
  126.  
  127.           if (cloneXref.ExtensionDictionary.IsNull)
  128.             cloneXref.CreateExtensionDictionary();
  129.  
  130.           Db.DBDictionary xDict = (Db.DBDictionary)tr.GetObject(cloneXref.ExtensionDictionary, Db.OpenMode.ForWrite);
  131.           if (xDict.Contains(filterDictName))
  132.           {
  133.             Db.DBDictionary fDict =
  134.               (Db.DBDictionary)tr.GetObject(
  135.                 xDict.GetAt(filterDictName), Db.OpenMode.ForWrite
  136.               );
  137.             if (fDict.Contains(spatialName))
  138.               fDict.Remove(spatialName);
  139.             fDict.SetAt(spatialName, sf);
  140.           }
  141.           else
  142.           {
  143.             using (Db.DBDictionary fDict = new Db.DBDictionary())
  144.             {
  145.               xDict.SetAt(filterDictName, fDict);
  146.               tr.AddNewlyCreatedDBObject(fDict, true);
  147.               fDict.SetAt(spatialName, sf);
  148.             }
  149.           }
  150.           tr.AddNewlyCreatedDBObject(sf, true);
  151.         }
  152.       }
  153.     }
  154.   }
  155. }
  156.  

Отмечено как Решение Владимир Шу 18-04-2019, 16:30:26

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Попробуй:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.DatabaseServices.Filters;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.Runtime;
  7. using System;
  8.  
  9. namespace SpatialFiltering
  10. {
  11.   public class ClipBlock
  12.   {
  13.     const string filterDictName = "ACAD_FILTER";
  14.     const string spatialName = "SPATIAL";
  15.  
  16.     [CommandMethod("MyXCLIP")]
  17.     public static void MyXCLIP()
  18.     {
  19.       Document doc =
  20.         Application.DocumentManager.MdiActiveDocument;
  21.       Database db = doc.Database;
  22.       Editor ed = doc.Editor;
  23.       Matrix3d matUcsWcs = ed.CurrentUserCoordinateSystem;
  24.       // Select a block to clip
  25.  
  26.       PromptEntityOptions peo =
  27.         new PromptEntityOptions(
  28.           "\nВыберите блок или внешнюю ссылку для подрезки:"
  29.         );
  30.  
  31.       peo.AllowNone = false;
  32.       peo.SetRejectMessage("\nЭто не блок и не внешняя ссылка.");
  33.       peo.AddAllowedClass(typeof(BlockReference), false);
  34.  
  35.       PromptEntityResult per = ed.GetEntity(peo);
  36.  
  37.       if (per.Status != PromptStatus.OK)
  38.         return;
  39.  
  40.       // Выбираем прямоугольник для подрезки
  41.  
  42.       PromptPointOptions ppo =
  43.         new PromptPointOptions("\nВыберите первый угол: ");
  44.       ppo.AllowNone = false;
  45.       PromptPointResult ppr = ed.GetPoint(ppo);
  46.  
  47.       if (ppr.Status != PromptStatus.OK)
  48.         return;
  49.  
  50.       Point3d pt1 = ppr.Value.TransformBy(matUcsWcs);
  51.       PromptCornerOptions pco =
  52.         new PromptCornerOptions("\nВыберите второй угол: ", pt1);
  53.  
  54.       ppr = ed.GetCorner(pco);
  55.  
  56.       if (ppr.Status != PromptStatus.OK)
  57.         return;
  58.  
  59.       Point3d pt2 = ppr.Value.TransformBy(matUcsWcs);
  60.  
  61.       // Используем эмуляцию транзакции!!!
  62.       Transaction tr = db.TransactionManager.StartOpenCloseTransaction();
  63.  
  64.       using (tr)
  65.       {
  66.  
  67.         // Преобразуем и упорядочиваем точки
  68.  
  69.         BlockReference br =
  70.           (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForRead);
  71.         pt1 = pt1.TransformBy(br.BlockTransform.Inverse());
  72.         pt2 = pt2.TransformBy(br.BlockTransform.Inverse());
  73.         Point2d rectMin =
  74.           new Point2d(
  75.             Math.Min(pt1.X, pt2.X),
  76.             Math.Min(pt1.Y, pt2.Y)
  77.           );
  78.  
  79.         Point2d rectMax =
  80.           new Point2d(
  81.             Math.Max(pt1.X, pt2.X),
  82.             Math.Max(pt1.Y, pt2.Y)
  83.           );
  84.  
  85.         Point2dCollection pts = new Point2dCollection(2) { rectMin, rectMax };
  86.  
  87.         SpatialFilterDefinition sfd =
  88.           new SpatialFilterDefinition(
  89.             pts, Vector3d.ZAxis, 0.0, 0.0, 0.0, true
  90.           );
  91.  
  92.         SpatialFilter sf = new SpatialFilter();
  93.  
  94.         // Создаём ExtDict если её нет
  95.  
  96.         ObjectId idbrExt = br.ExtensionDictionary;
  97.  
  98.         if (idbrExt == ObjectId.Null)
  99.         {
  100.           br.UpgradeOpen();
  101.           br.CreateExtensionDictionary();
  102.           idbrExt = br.ExtensionDictionary;
  103.           br.DowngradeOpen();
  104.         }
  105.  
  106.  
  107.         // Добавляем фильтр в ExtDict
  108.  
  109.         DBDictionary xDict =
  110.           (DBDictionary)tr.GetObject(
  111.             idbrExt, OpenMode.ForWrite
  112.           );
  113.         if (xDict.Contains(filterDictName))
  114.         {
  115.           DBDictionary fDict =
  116.             (DBDictionary)tr.GetObject(
  117.               xDict.GetAt(filterDictName), OpenMode.ForWrite
  118.             );
  119.           if (fDict.Contains(spatialName))
  120.             fDict.Remove(spatialName);
  121.           fDict.SetAt(spatialName, sf);
  122.         }
  123.         else
  124.         {
  125.           DBDictionary fDict = new DBDictionary();
  126.           xDict.SetAt(filterDictName, fDict);
  127.           tr.AddNewlyCreatedDBObject(fDict, true);
  128.           fDict.SetAt(spatialName, sf);
  129.         }
  130.  
  131.        
  132.         sf.Definition = sfd;
  133.  
  134.         tr.AddNewlyCreatedDBObject(sf, true);
  135.  
  136.         tr.Commit();
  137.       }
  138.  
  139.       ed.Regen();
  140.     }
  141.   }
  142. }
  143.  

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

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Есть еще один вариант:
Код - C# [Выбрать]
  1. [DllImport("acdb23.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl,
  2. EntryPoint = "?addFilter@AcDbIndexFilterManager@@YA?AW4ErrorStatus@Acad@@PAVAcDbBlockReference@@PAVAcDbFilter@@@Z")]
  3. private static extern int addFilter32(IntPtr pBlkRef, IntPtr pFilter);
  4.  
  5. [DllImport("acdb23.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl,
  6. EntryPoint = "?addFilter@AcDbIndexFilterManager@@YA?AW4ErrorStatus@Acad@@PEAVAcDbBlockReference@@PEAVAcDbFilter@@@Z")]
  7. private static extern int addFilter64(IntPtr pBlkRef, IntPtr pFilter);
  8.  
  9. [CommandMethod("MyXCLIP2")]
  10. public static void MyXCLIP2()
  11. {
  12.   Document doc =
  13.     Application.DocumentManager.MdiActiveDocument;
  14.   Database db = doc.Database;
  15.   Editor ed = doc.Editor;
  16.   Matrix3d matUcsWcs = ed.CurrentUserCoordinateSystem;
  17.   // Select a block to clip
  18.  
  19.   PromptEntityOptions peo =
  20.     new PromptEntityOptions(
  21.       "\nВыберите блок или внешнюю ссылку для подрезки:"
  22.     );
  23.  
  24.   peo.AllowNone = false;
  25.   peo.SetRejectMessage("\nЭто не блок и не внешняя ссылка.");
  26.   peo.AddAllowedClass(typeof(BlockReference), false);
  27.  
  28.   PromptEntityResult per = ed.GetEntity(peo);
  29.  
  30.   if (per.Status != PromptStatus.OK)
  31.     return;
  32.  
  33.   // Выбираем прямоугольник для подрезки
  34.  
  35.   PromptPointOptions ppo =
  36.     new PromptPointOptions("\nВыберите первый угол: ");
  37.   ppo.AllowNone = false;
  38.   PromptPointResult ppr = ed.GetPoint(ppo);
  39.  
  40.   if (ppr.Status != PromptStatus.OK)
  41.     return;
  42.  
  43.   Point3d pt1 = ppr.Value.TransformBy(matUcsWcs);
  44.   PromptCornerOptions pco =
  45.     new PromptCornerOptions("\nВыберите второй угол: ", pt1);
  46.  
  47.   ppr = ed.GetCorner(pco);
  48.  
  49.   if (ppr.Status != PromptStatus.OK)
  50.     return;
  51.  
  52.   Point3d pt2 = ppr.Value.TransformBy(matUcsWcs);
  53.  
  54.   // Используем эмуляцию транзакции!!!
  55.   Transaction tr = db.TransactionManager.StartOpenCloseTransaction();
  56.  
  57.   using (tr)
  58.   {
  59.  
  60.     // Преобразуем и упорядочиваем точки
  61.  
  62.     BlockReference br =
  63.       (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForWrite);
  64.     pt1 = pt1.TransformBy(br.BlockTransform.Inverse());
  65.     pt2 = pt2.TransformBy(br.BlockTransform.Inverse());
  66.     Point2d rectMin =
  67.       new Point2d(
  68.         Math.Min(pt1.X, pt2.X),
  69.         Math.Min(pt1.Y, pt2.Y)
  70.       );
  71.  
  72.     Point2d rectMax =
  73.       new Point2d(
  74.         Math.Max(pt1.X, pt2.X),
  75.         Math.Max(pt1.Y, pt2.Y)
  76.       );
  77.  
  78.     Point2dCollection pts = new Point2dCollection(2) { rectMin, rectMax };
  79.  
  80.     SpatialFilter sf = new SpatialFilter();
  81.  
  82.     SpatialFilterDefinition sfd =
  83.       new SpatialFilterDefinition(
  84.         pts, Vector3d.ZAxis, 0.0, 0.0, 0.0, true
  85.       );
  86.  
  87.     if (IntPtr.Size == 8)
  88.       addFilter64(br.UnmanagedObject, sf.UnmanagedObject);
  89.     else
  90.       addFilter32(br.UnmanagedObject, sf.UnmanagedObject);
  91.     sf.Definition = sfd;
  92.     tr.AddNewlyCreatedDBObject(sf, true);
  93.     br.RecordGraphicsModified(true);
  94.  
  95.     tr.Commit();
  96.   }
  97.  
  98.   ed.Regen();
  99. }
  100.  
Для AutoCAD 2017 вместо acdb23.dll должно быть acdb21.dll
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир ШуАвтор темы

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

Коммент к коду, если при создании  sfd использовать pts1, т.е. макс и мин точки, то вставка Xref создается, но ее не видно и ручек нет, если использовать pts, т.е. не макс и мин координаты, то выхватываю ошибку на 184 строке, но если это присвоение (sf.Definition = sfd;) перенести в район 148 строки, то ошибки нет
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using App = Autodesk.AutoCAD.ApplicationServices;
  4. using Db = Autodesk.AutoCAD.DatabaseServices;
  5. using Ed = Autodesk.AutoCAD.EditorInput;
  6. using Gem = Autodesk.AutoCAD.Geometry;
  7. using Rtm = Autodesk.AutoCAD.Runtime;
  8.  
  9. [assembly: Rtm.CommandClass(typeof(ClipedXref.Test))]
  10. namespace ClipedXref
  11. {
  12.   class Test
  13.   {
  14.     private static double XRefWidth { get; set; } = 10;
  15.     const string filterDictName = "ACAD_FILTER";
  16.     const string spatialName = "SPATIAL";
  17.  
  18.     [Rtm.CommandMethod("zz")]
  19.     public static void ClipedXref()
  20.     {
  21.       App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
  22.       if (acDoc == null) return;
  23.       Db.Database acCurDb = acDoc.Database;
  24.       Ed.Editor acEd = acDoc.Editor;
  25.  
  26.       Db.BlockReference cloneXref = null;
  27.       List<Gem.Point3d> ptsIn = new List<Gem.Point3d>();
  28.  
  29.  
  30.       Ed.PromptEntityOptions opt = new Ed.PromptEntityOptions($"\n\nSelect line in XRef:");
  31.       opt.AllowNone = false;
  32.       opt.AllowObjectOnLockedLayer = true;
  33.       opt.SetRejectMessage("\nYou must select XRef!");
  34.       opt.AddAllowedClass(typeof(Db.BlockReference), true);
  35.  
  36.       Ed.PromptEntityResult res = acEd.GetEntity(opt);
  37.       if (res.Status != Ed.PromptStatus.OK) return;
  38.  
  39.       if (res.ObjectId.ObjectClass.IsDerivedFrom(Rtm.RXClass.GetClass(typeof(Db.BlockReference))))
  40.       {
  41.         using (Db.BlockReference br = res.ObjectId.Open(Db.OpenMode.ForRead) as Db.BlockReference)
  42.         {
  43.           Db.ObjectId btrId = br.BlockTableRecord;
  44.           using (Db.BlockTableRecord btr = btrId.Open(Db.OpenMode.ForRead) as Db.BlockTableRecord)
  45.           {
  46.             if (btr.IsFromExternalReference)
  47.             {
  48.               Ed.PromptNestedEntityOptions pneo = new Ed.PromptNestedEntityOptions("");
  49.               pneo.NonInteractivePickPoint = res.PickedPoint;
  50.               pneo.UseNonInteractivePickPoint = true;
  51.               Ed.PromptNestedEntityResult pner = acEd.GetNestedEntity(pneo);
  52.  
  53.               if (pner.Status == Ed.PromptStatus.OK)
  54.               {
  55.                 Db.ObjectId selId = pner.ObjectId;
  56.                 if (selId.ObjectClass.IsDerivedFrom(Rtm.RXClass.GetClass(typeof(Db.Line))))
  57.                 {
  58.                   cloneXref = br.Clone() as Db.BlockReference;
  59.                   using (Db.Line line = selId.Open(Db.OpenMode.ForRead) as Db.Line)
  60.                   {
  61.                     ptsIn.Add(line.StartPoint);
  62.                     ptsIn.Add(line.EndPoint);
  63.                   }
  64.                 }
  65.               }
  66.             }
  67.           }
  68.         }
  69.       }
  70.  
  71.       if (cloneXref != null && ptsIn.Count > 0)
  72.       {
  73.         Ed.PromptPointOptions optPnt = new Ed.PromptPointOptions("\nPick a point to insert XRef: ");
  74.         optPnt.AllowNone = false;
  75.         Ed.PromptPointResult resPnt = acEd.GetPoint(optPnt);
  76.         if (resPnt.Status == Ed.PromptStatus.OK)
  77.         {
  78.           Gem.Matrix3d mat = cloneXref.BlockTransform;
  79.           Gem.Vector3d v1 = ptsIn[0].TransformBy(mat).GetVectorTo(resPnt.Value);
  80.           for (int i = 0; i < ptsIn.Count; i++)
  81.             ptsIn[i] = ptsIn[i].TransformBy(mat) + v1;
  82.  
  83.           CreateEXref(acCurDb.CurrentSpaceId, cloneXref, ptsIn, XRefWidth, v1);
  84.         }
  85.       }
  86.       acEd.Regen();
  87.     }
  88.  
  89.  
  90.     private static void CreateEXref(Db.ObjectId CurrentSpaceId, Db.BlockReference cloneXref1, List<Gem.Point3d> ptsIn, double dist, Gem.Vector3d v1)
  91.     {
  92.       App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
  93.       Db.Database acCurDb = acDoc.Database;
  94.  
  95.       for (int i = 0; i < ptsIn.Count - 1; i++)
  96.       {
  97.         Db.ObjectId id = Db.ObjectId.Null;
  98.         using (Db.Transaction tr = acCurDb.TransactionManager.StartTransaction())
  99.         {
  100.           Db.BlockTableRecord acBlkTblRec = tr.GetObject(CurrentSpaceId, Db.OpenMode.ForWrite) as Db.BlockTableRecord;
  101.           cloneXref1.TransformBy(Gem.Matrix3d.Displacement(v1));
  102.           id = acBlkTblRec.AppendEntity(cloneXref1);
  103.           tr.AddNewlyCreatedDBObject(cloneXref1, true);
  104.           tr.Commit();
  105.         }
  106.  
  107.         using (Db.Transaction tr = acCurDb.TransactionManager.StartOpenCloseTransaction())
  108.         {
  109.  
  110.           Db.BlockReference cloneXref = (Db.BlockReference)tr.GetObject(id, Db.OpenMode.ForRead);
  111.  
  112.           Gem.Point3dCollection pts3d = new Gem.Point3dCollection();
  113.           Gem.Vector3d vG = ptsIn[i].GetVectorTo(ptsIn[i + 1]);
  114.           Gem.Vector3d vV = vG.GetPerpendicularVector().GetNormal() * dist / 2;
  115.  
  116.           pts3d.Add(ptsIn[i] - vV);
  117.           pts3d.Add(ptsIn[i] + vG + vV);
  118.  
  119.           Gem.Point2dCollection pts = new Gem.Point2dCollection(pts3d.Count);
  120.           Gem.Matrix3d mat = cloneXref.BlockTransform.Inverse();
  121.           foreach (Gem.Point3d p in pts3d)
  122.           {
  123.             Gem.Point3d pBlk = p.TransformBy(mat);
  124.             pts.Add(new Gem.Point2d(pBlk.X, pBlk.Y));
  125.           }
  126.  
  127.  
  128.  
  129.           Gem.Point2d rectMin = new Gem.Point2d(
  130.     Math.Min(pts3d[0].X, pts3d[1].X),
  131.     Math.Min(pts3d[0].Y, pts3d[1].Y)
  132.   );
  133.  
  134.           Gem.Point2d rectMax = new Gem.Point2d(
  135.     Math.Max(pts3d[0].X, pts3d[1].X),
  136.     Math.Max(pts3d[0].Y, pts3d[1].Y)
  137.             );
  138.  
  139.  
  140.           Gem.Point2dCollection pts1 = new Gem.Point2dCollection(2) { rectMin, rectMax };
  141.  
  142.           Db.Filters.SpatialFilterDefinition sfd =
  143.   new Db.Filters.SpatialFilterDefinition(
  144.     pts1, Gem.Vector3d.ZAxis, 0.0, 0.0, 0.0, true
  145.   );
  146.  
  147.           Db.Filters.SpatialFilter sf = new Db.Filters.SpatialFilter();
  148.  
  149.           // Создаём ExtDict если её нет
  150.           Db.ObjectId idbrExt = cloneXref.ExtensionDictionary;
  151.  
  152.           if (idbrExt == Db.ObjectId.Null)
  153.           {
  154.             cloneXref.UpgradeOpen();
  155.             cloneXref.CreateExtensionDictionary();
  156.             idbrExt = cloneXref.ExtensionDictionary;
  157.             cloneXref.DowngradeOpen();
  158.           }
  159.  
  160.  
  161.           // Добавляем фильтр в ExtDict
  162.           Db.DBDictionary xDict =
  163.             (Db.DBDictionary)tr.GetObject(
  164.               idbrExt, Db.OpenMode.ForWrite
  165.             );
  166.           if (xDict.Contains(filterDictName))
  167.           {
  168.             Db.DBDictionary fDict =
  169.               (Db.DBDictionary)tr.GetObject(
  170.                 xDict.GetAt(filterDictName), Db.OpenMode.ForWrite
  171.               );
  172.             if (fDict.Contains(spatialName))
  173.               fDict.Remove(spatialName);
  174.             fDict.SetAt(spatialName, sf);
  175.           }
  176.           else
  177.           {
  178.             Db.DBDictionary fDict = new Db.DBDictionary();
  179.             xDict.SetAt(filterDictName, fDict);
  180.             tr.AddNewlyCreatedDBObject(fDict, true);
  181.             fDict.SetAt(spatialName, sf);
  182.           }
  183.  
  184.           sf.Definition = sfd;
  185.  
  186.           tr.AddNewlyCreatedDBObject(sf, true);
  187.           cloneXref.RecordGraphicsModified(true);
  188.  
  189.           tr.Commit();
  190.         }
  191.       }
  192.     }
  193.   }
  194. }
  195.  

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

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

Оффлайн Владимир ШуАвтор темы

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

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

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