Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Александр Пекшев aka Modis от 03-04-2014, 22:56:55

Название: Не работает вставка
Отправлено: Александр Пекшев aka Modis от 03-04-2014, 22:56:55
Всем доброго времени суток. Не работает вставка в текущий чертеж из другого чертежа. Код был найден на просторах инета (с отрисовкой на курсоре):
Код - C# [Выбрать]
  1. public static void InsertFromDwgFile(string fileName)
  2.         {
  3.             try
  4.             {
  5.  
  6.                 SetFocus(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Window.Handle);
  7.  
  8.                 Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  9.  
  10.                 Editor ed = doc.Editor;
  11.  
  12.                 Point3d ptNew = Point3d.Origin;
  13.  
  14.  
  15.                 using (doc.LockDocument())
  16.                 {
  17.  
  18.                     Database currentDb = doc.Database;
  19.  
  20.                     ObjectIdCollection ids = new ObjectIdCollection();
  21.  
  22.                     IdMapping idMap = new IdMapping();
  23.  
  24.                     using (Transaction tr = doc.TransactionManager.StartTransaction())
  25.                     {
  26.  
  27.                         BlockTable currBt = (BlockTable)tr.GetObject(currentDb.BlockTableId, OpenMode.ForRead);
  28.  
  29.                         BlockTableRecord currBtr =
  30.                             (BlockTableRecord)tr.GetObject(currBt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  31.  
  32.                         using (Database sourceDb = new Database(false, false))
  33.                         {
  34.  
  35.                             sourceDb.ReadDwgFile(fileName, System.IO.FileShare.ReadWrite, false, "");
  36.  
  37.                             using (Transaction sourcetr = sourceDb.TransactionManager.StartTransaction())
  38.                             {
  39.  
  40.                                 ObjectIdCollection­ sourceIds = new ObjectIdCollection();
  41.  
  42.                                 using (
  43.                                     BlockTableReco­rd sourceBtr =
  44.                                         (BlockTableRecord)sourcetr.GetObject(sourceDb.CurrentSpaceId, OpenMode.ForRead)
  45.                                     )
  46.                                 {
  47.  
  48.                                     if (sourceBtr != null)
  49.                                     {
  50.  
  51.                                         sourceIds = new ObjectIdCollection();
  52.  
  53.                                         foreach (ObjectId id in sourceBtr)
  54.                                         {
  55.                                             if (!id.IsNull && id.IsValid) //optional
  56.                                                 so­urceIds.Add(id);
  57.                                         }
  58.  
  59.                                         sourcetr.Commit();
  60.                                     }
  61.  
  62.                                     if (sourceIds.Count != 0)
  63.                                         idMap = new IdMapping();
  64.  
  65.                                     sourceDb.WblockCloneObjects(sourceIds, currBtr.ObjectId, idMap,
  66.                                                   ­              DuplicateRecordCloning.Ignore, false);
  67.  
  68.                                 }
  69.  
  70.                             }
  71.                         }
  72.  
  73.  
  74.                         foreach (IdPair ip in idMap)
  75.                         {
  76.                             if (ip.IsPrimary) ids.Add(ip.Value);
  77.  
  78.                         }
  79.  
  80.  
  81.                         var copied = new ObjectId[ids.Count];
  82.  
  83.                         ids.CopyTo(copied, 0);
  84.  
  85.                         ed.SetImpliedSelection(copied);
  86.  
  87.                         PromptSelectionResult psr = ed.SelectImplied();
  88.  
  89.                         if (psr.Status == PromptStatus.OK)
  90.                         {
  91.                             var ppr =
  92.                                 ed.Drag(
  93.                                     psr.Value,
  94.                                     "\nУкажите точку вставки: ",
  95.                                     delegate(Point3d pt, ref Matrix3d mtx)
  96.                                     {
  97.  
  98.                                         if (ptNew == pt)
  99.                                         {
  100.                                             return­ SamplerStatus.NoChange;
  101.                                         }
  102.                                         mtx =
  103.                                             Matrix­3d.Displacement(
  104.                                                 pt­New.GetVectorTo(pt)
  105.                                                 );
  106.                                         return SamplerStatus.OK;
  107.                                     }
  108.                                     );
  109.  
  110.  
  111.                             if (ppr.Status == PromptStatus.OK)
  112.                             {
  113.  
  114.                                 var mtx =
  115.                                     Matrix3d.Displacement(
  116.                                         ptNew.GetVectorTo(ppr.Value)
  117.                                         );
  118.                                 foreach (SelectedObject sobj in psr.Value)
  119.                                 {
  120.                                     var en = tr.GetObject(sobj.ObjectId, OpenMode.ForRead, false) as Entity;
  121.                                     if (en != null)
  122.                                     {
  123.                                         en.UpgradeOpen();
  124.                                         en.TransformBy(mtx);
  125.                                         en.DowngradeOpen();
  126.                                     }
  127.                                 }
  128.                             }
  129.                             else
  130.                             {
  131.                                 foreach (SelectedObject sobj in psr.Value)
  132.                                 {
  133.                                     var en = tr.GetObject(sobj.ObjectId, OpenMode.ForWrite, false) as Entity;
  134.                                     if (en != null)
  135.                                     {
  136.                                         en.Erase(true);
  137.                                     }
  138.                                 }
  139.                             }
  140.                             ed.SetImpliedSelection(new ObjectId[] { });
  141.  
  142.                             tr.Commit();
  143.  
  144.                         }
  145.                     }
  146.                 }
  147.             }
  148.  
  149.             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  150.             {
  151.                 Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message + "\n" + ex.StackTrace + "\n" + ex.TargetSite);
  152.             }
  153.         }
Вся фишка в том, что у меня работает, а у человека в другом городе - нет. И я не могу понять почему.
Не работает после указания точки вставки. Т.е. на курсоре все отрисовывается
Скрин ошибки прилагаю. Надеюсь на свежие идеи)
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs9.uploads.ru%2Fe3XNI.jpg&hash=4860be3003ac9c184233aacd7eefc8e6)
Название: Re: Не работает вставка
Отправлено: Александр Ривилис от 04-04-2014, 02:01:26
Приветствую на форуме!
1) Судя по коду ошибки она происходит в цикле:
Код - C# [Выбрать]
  1. foreach (SelectedObject sobj in psr.Value)
2) Не пользуйся создание набора предварительного выбора (ed.SetImpliedSelection), а создавай свой честный набор, передавай его в ed.Drag, ну и дальше по тексту.
3) В цикле:
Код - C# [Выбрать]
  1. foreach (IdPair ip in idMap)
  2. {
  3.    if (ip.IsPrimary) ids.Add(ip.Value);
  4. }
  5.  
рекомендую проверять не только ip.IsPrimary, но и то, что ip.Value - это ObjectId для Entity (в набор можно включить только Entity)
4) Не понятно место нахождения sourcetr.Commit(); У тебя в большинстве случаев этот код не выполняется.

Это несколько замечаний, которые я сразу увидел в коде. Замечание 2) считаю самым принципиальным.
 
Название: Re: Не работает вставка
Отправлено: Александр Пекшев aka Modis от 04-04-2014, 11:01:51
Александр, спасибо вам.
Вся проблема в том, что я уже как-то забросил все это дело. Сам уже года 4 как с автокадом не работаю. Но вот отголоски прошлого не дают покоя )

Самое главное - в чем проблема - у меня все те-же действия со вставкой тех-же самых чертежей - все работает!!!
А в другом городе, на другом компе - нет
Название: Re: Не работает вставка
Отправлено: Александр Ривилис от 04-04-2014, 14:55:17
Самое главное - в чем проблема - у меня все те-же действия со вставкой тех-же самых чертежей - все работает!!!
А в другом городе, на другом компе - нет
Это как раз естественно. Возможно разные версии AutoCAD, возможно отсутствие SP, возможно разные настройки AutoCAD (отличаются системные переменные, например PICKFIRST) и т.д. Так что код нужно сделать максимально "чистым".
Название: Re: Не работает вставка
Отправлено: Алексей (IdeaSoft) от 11-02-2016, 00:18:25
Это нормально у меня похожая ситуация бывает с функциями, когда забываю поменять сборки NET (64bit или 32bit).
Уточните версию ОС Windows AutoCAD на другом компе 64bit или 32bit?
Попробуйте поменять сборки (net autocad) в проекте visual studio на соотв. битность ОС.

Название: Re: Не работает вставка
Отправлено: Александр Ривилис от 11-02-2016, 01:23:42
Это нормально у меня похожая ситуация бывает с функциями, когда забываю поменять сборки NET (64bit или 32bit).
Уточните версию ОС Windows AutoCAD на другом компе 64bit или 32bit?
Попробуйте поменять сборки (net autocad) в проекте visual studio на соотв. битность ОС.
Начиная с AutoCAD 2011 сборки AcDbMgd.dll AcMgd.dll AcWindows.dll AdWindows.dll AcCui.dll не зависят от разрядности AutoCAD. Достаточно использовать их из каталога ObjectARX\inc, установив для них в параметрах Copy Local в False и Platform в AnyCPU. Только если используются COM/ActiveX-сборки AutoCAD или сторонние сборки может возникнуть зависимость от разрядности AutoCAD/Windows.
Название: Re: Не работает вставка
Отправлено: Алексей (IdeaSoft) от 11-02-2016, 09:30:00
Начиная с AutoCAD 2011 сборки AcDbMgd.dll AcMgd.dll
Я два дня назад в одной компании устанавливал свой софт сотруднику у которого Windows XP 32bit.
И хочу отметить следующее. Моя сборка к которой я подключил файлы AcDbMgd.dll AcMgd.dll
из версии AutoCAD 64bit не загрузилаcь в AutoCAD 2011 32bit
Хотя там были подключены сборки NET FrmaWork 4.5, что тоже важно для AutoCAD 2011 Net должен быть 3.5.
А ничего страшного, что сборки AcDbMgd.dll AcMgd.dll для 64bit и 32bit разные по размеру?

Название: Re: Не работает вставка
Отправлено: Александр Ривилис от 11-02-2016, 09:42:50
И хочу отметить следующее. Моя сборка к которой я подключил файлы AcDbMgd.dll AcMgd.dll
из версии AutoCAD 64bit не загрузилаcь в AutoCAD 2011 32bit
И почему меня это не удивляет? ;)
Название: Re: Не работает вставка
Отправлено: Алексей (IdeaSoft) от 11-02-2016, 10:04:29
И почему меня это не удивляет?
Меня тоже не удивляет, т.к. библы написанные для 64bit не должны работать в 32bit
Название: Re: Не работает вставка
Отправлено: Александр Ривилис от 11-02-2016, 10:08:52
Меня тоже не удивляет, т.к. библы написанные для 64bit не должны работать в 32bit
Итак. Повторюсь (главное выделил жирным):
Начиная с AutoCAD 2011 сборки AcDbMgd.dll AcMgd.dll AcWindows.dll AdWindows.dll AcCui.dll не зависят от разрядности AutoCAD. Достаточно использовать их из каталога ObjectARX\inc, установив для них в параметрах Copy Local в False и Platform в AnyCPU. Только если используются COM/ActiveX-сборки AutoCAD или сторонние сборки может возникнуть зависимость от разрядности AutoCAD/Windows.
Соотвественно "библы" не написанные под конкретную разрядность будут работать и там и там.
Название: Re: Не работает вставка
Отправлено: Алексей (IdeaSoft) от 11-02-2016, 10:19:12
Соотвественно "библы" не написанные под конкретную разрядность будут работать и там и там
Я еще раз проверю это. Что бы убедится что все работает.
Название: Re: Не работает вставка
Отправлено: Александр Ривилис от 11-02-2016, 12:00:15
Я еще раз проверю это. Что бы убедится что все работает.
И это правильно. И само собой еще есть зависимость от версии сборок AutoCAD. Т.е. если собирал со сборками AutoCAD 2013 в 2011 работать не будет - не найдет AcCoreMgd.dll - но тут уже разрядность не причем.
Название: Re: Не работает вставка
Отправлено: Андрей Бушман от 11-02-2016, 15:04:39
Моя сборка к которой я подключил файлы AcDbMgd.dll AcMgd.dll
из версии AutoCAD 64bit не загрузилаcь в AutoCAD 2011 32bit
Ключевой момент подсвечен. :)

Когда я не использую COM (т.е. почти всегда), то компилирую свой код в двух вариантах:

1. Для AutoCAD 2009 (использую DLL файлы из подкаталога inc-x64) - AnyCPU. Результат компиляции успешно работает в AutoCAD 2009-2012.
2. Для AutoCAD 2013 (использую DLL файлы из подкаталога inc) - AnyCPU. Результат компиляции успешно работает в AutoCAD 2013 и всех более новых.

Те немногие юзеры (искользующие мой код), которые до сих пор сидят на 32bit, каких-либо проблем так же не замечали.

Если мне, по какой-то причине, всё же необходимо обратиться к тому или иному функционалу COM (например - работа с подшивками), то использую позднее связывание. Это позволяет всегда собирать мои сборки под AnyCPU.