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

ADN Club => AutoCAD .NET API => Тема начата: avk561 от 24-02-2018, 14:11:56

Название: Вставка блока мышкой
Отправлено: avk561 от 24-02-2018, 14:11:56
Есть блок   TEST(), его надо вставить мышкой, при этом он должен отображаться при перемещении мышки. Ошибка в строке  23.  Какой метод использовать?

 
Код - C# [Выбрать]
  1. public Db.ObjectId TEST()
  2.         {
  3.      ------код-------
  4.                     newBtrId19 = bt["Однолинейная"];
  5.                 ------код-------
  6.         }
  7.  
  8.  
  9.        public class BlockJigCmds
  10.        {
  11.             //  Попросите пользователя разместить блок с именем «TEST», показывая его во время перетаскивания.
  12.             //  Убедитесь, что блок с этим именем существует в чертеже.
  13.             [Rt.CommandMethod("BlockJig")]
  14.            static  public void BlockJig()
  15.             {
  16.                 Ed.Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;//Получить доступ к редактору  
  17.                 Db.Database db = ed.Document.Database;
  18.                 try
  19.                 {                  
  20.                     using (Db.Transaction tr = db.TransactionManager.StartTransaction())
  21.                     {                  
  22.                         Db.BlockTable bt = (Db.BlockTable)(tr.GetObject(db.BlockTableId, Db.OpenMode.ForRead));
  23.                         Db.BlockTableRecord btr = (Db.BlockTableRecord)tr.GetObject(bt["Однолинейная"], Db.OpenMode.ForRead);                        
  24.                         // Создайте Jig и попросите пользователя разместить блок
  25.                         MyBlockJig blockJig = new MyBlockJig();
  26.                         Gm.Point3d point;
  27.                         Ed.PromptResult res = blockJig.DragMe(btr.ObjectId, out point);
  28.                         if (res.Status == Ed.PromptStatus.OK)
  29.                         {
  30.                             // Теперь нужно сделать обычные шаги, чтобы вставить блок в точку, в котором пользователь сделал щелчок
  31.                             Db.BlockTableRecord curSpace = (Db.BlockTableRecord)tr.GetObject(db.CurrentSpaceId, Db.OpenMode.ForWrite);                        
  32.                         Db.BlockReference insert = new Db.BlockReference(point, btr.ObjectId);
  33.                         curSpace.AppendEntity(insert); tr.AddNewlyCreatedDBObject(insert, true);
  34.                         }
  35.                         tr.Commit();
  36.                     } // using          
  37.                 }
  38.  
  39.                 catch (System.Exception ex)
  40.                 {
  41.                     ed.WriteMessage(ex.ToString());
  42.                 }
  43.             } // BlockJig()
  44.         } // class BlockJigCmds
  45.           //  Этот Jig покажет данный блок во время перетаскивания.
  46.         public class MyBlockJig : Ed.DrawJig
  47.         {
  48.             public Gm.Point3d _point;
  49.             private Db.ObjectId _blockId = Db.ObjectId.Null;
  50.             // Показывает блок, пока пользователь не нажмет на него. Первый параметр - это идентификатор определения блока.
  51.             // Второй - это щелчок.      
  52.             public Ed.PromptResult DragMe(Db.ObjectId i_blockId, out Gm.Point3d o_pnt)
  53.             {
  54.                 _blockId = i_blockId;
  55.                 Ed.Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;//Получить доступ к редактору                                                                                
  56.                 Ed.PromptResult jigRes = ed.Drag(this);
  57.                 o_pnt = _point;
  58.                 return jigRes;
  59.             }
  60.             // Необходимо переопределить этот метод. Обновление текущей позиции блока.
  61.             protected override Ed.SamplerStatus Sampler(Ed.JigPrompts prompts)
  62.             {
  63.                 Ed.JigPromptPointOptions jigOpts = new Ed.JigPromptPointOptions();
  64.                 jigOpts.UserInputControls = (Ed.UserInputControls.Accept3dCoordinates | Ed.UserInputControls.NullResponseAccepted);
  65.                 jigOpts.Message = "Выбор точки вставки:";
  66.                 Ed.PromptPointResult jigRes = prompts.AcquirePoint(jigOpts);
  67.                 Gm.Point3d pt = jigRes.Value;
  68.                 if (pt == _point)
  69.                     return Ed.SamplerStatus.NoChange;
  70.                 _point = pt;
  71.                 if (jigRes.Status == Ed.PromptStatus.OK)
  72.                     return Ed.SamplerStatus.OK;
  73.                 return Ed.SamplerStatus.Cancel;
  74.             }
  75.             //Необходимо переопределить этот метод. Мы показываем наш блок в его текущей позиции здесь.
  76.             protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
  77.             {
  78.                 Db.BlockReference inMemoryBlockInsert = new Db.BlockReference(_point, _blockId);
  79.                 draw.Geometry.Draw(inMemoryBlockInsert);
  80.                 inMemoryBlockInsert.Dispose();
  81.                 return true;
  82.             } // WorldDraw()
  83.         } // class BlockJig

/* Предупреждение за редактирование собственного сообщения, после того как на него был дан ответ и не один. Александр Ривилис */
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 24-02-2018, 19:30:06
Так ошибка-то какая?
Название: Re: Вставка блока мышкой
Отправлено: avk561 от 24-02-2018, 19:44:59
Показывает на эту строку, а вообще код брал из примера для вставки блока из пространства чертежа в этот же чертёж.
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 24-02-2018, 19:46:59
Показывает на эту строку
Повторяю вопрос - ошибка какая???
Название: Re: Вставка блока мышкой
Отправлено: Александр Ривилис от 24-02-2018, 19:54:27
Код жуткий. Бездумно надергано из разных функций. В строке 33 не хватает tr.Commit();
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 24-02-2018, 19:56:41
В строке 33 не хватает tr.Commit();
Могу предположить, что в 55 строке NullReferenceException eKeyNotFound, так как в методе TEST() не создается блока по причине отсутствия tr.Commit()
Название: Re: Вставка блока мышкой
Отправлено: avk561 от 24-02-2018, 20:17:05
С 1 по 39 строку- Это создаётся блок, он рабочий на 100%. Теперь его надо вставить мышкой . ************** Текст исключения **************
Autodesk.AutoCAD.Runtime.Exception: eKeyNotFound
   в Autodesk.AutoCAD.DatabaseServices.SymbolTable.get_Item(String key)
   в RibbonElektro.Form1.BlockJigCmds.BlockJig()
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 24-02-2018, 20:18:30
он рабочий на 100%
Он на 100% НЕ РАБОЧИЙ! И вам уже объяснили почему
Название: Re: Вставка блока мышкой
Отправлено: avk561 от 24-02-2018, 21:37:19
В строке 33 не хватает tr.Commit();
Могу предположить, что в 55 строке NullReferenceException eKeyNotFound, так как в методе TEST() не создается блока по причине отсутствия tr.Commit()
Ни какой жути нет. Все примеры беру отсюда, вырезаю, склеиваю, затачиваю http://adndevblog.typepad.com/autocad/2012/07/how-to-show-a-block-when-positioning-it-using-c.html и перевожу на русский!
Блок исправен. Как его вставить мышкой?
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 24-02-2018, 21:59:28
avk561, вы прикалываетесь или издеваетесь? Вам уже ответили - в вашем методе TEST() НЕ СОЗДАЕТСЯ блок, так как транзакцию нужно зафиксировать, вызвав метод tr.Commit(). У вас этого метода НЕ ВЫЗЫВАЕТСЯ, а, соответсвенно, все произведенные действия (создание блока в текущем примере) НЕ сохраняются в базе данных чертежа. Поэтому в строке 55 у вас ошибка, ибо ТАКОГО БЛОКА НЕ СУЩЕСТВУЕТ!!!
Название: Re: Вставка блока мышкой
Отправлено: avk561 от 24-02-2018, 22:10:37
Ваш ответ в стиле флуда. За эти 3 ч уже перепробовал массу вариантов, но не продвинулся. Блока не существует на чертеже, что подразумевает следующий класс.
Название: Re: Вставка блока мышкой
Отправлено: Алексей Кулик от 24-02-2018, 22:52:47
Off-Topic: показать
Мне кажется (если не прав, поправьте) - именно в строке надо добавлять tr.Commit(). Это так?
Учитывая, что я .NET от слова "никак"...
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 24-02-2018, 23:28:46
именно в строке надо добавлять tr.Commit(). Это так?
Да, нужно добавить tr.Commit() в некогда бывшей строке 33 части кода, которую автор зачем-то стёр. Ему Александр Ривилис указал, что ошибка именно там. Я ему разжевал почему у него не работает, а AutoCAD ему доказал это выводом ошибки eKeyNotFound.
Я понятия не имею, чего ждёт от нас автор вопроса. Мы ему указали где ошибка, но...
Название: Re: Вставка блока мышкой
Отправлено: Александр Ривилис от 24-02-2018, 23:29:22
avk561
Вы действительно прикалываетесь? Я персонально Вам запрещу редактировать Ваши сообщения после того, как на них дан ответ. Теперь мой ответ повис в воздухе, так как номер строки 33 уже не там, где был (в функции TEST), где Вы пытались создавать блок "Однолинейная", но не было tr.Commit() и поэтому блок "Однолинейная" не создавался - происходил откат транзакции.
Ошибка eKeyNotFound означает что блока "Однолинейная".
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 24-02-2018, 23:31:24
Блока не существует на чертеже, что подразумевает следующий класс
Блок должен существовать в базе данных чертежа откуда вы и пытаетесь его взять. Но его там НЕТ, о чем вам сообщил автокад ошибкой eKeyNotFound. А причина проста - вы его не создали! И мы уже пол вечера убили на то, чтобы доказать вам, что добавление всего-лишь одной строчки решит проблему!
Название: Re: Вставка блока мышкой
Отправлено: Алексей Кулик от 24-02-2018, 23:31:41
Off-Topic: показать
Александр Пекшев aka Modis, уау! Я даже что-то почти угадал :) Круто, можно спокойно пить пиво :)
P.S. не знаю, почему не прошло - но номер строки в моем сообщении был то ли 33, то ли 34...
P.P.S. Надо начинать полностью цитировать сообщения, на которые выполняется ответ ;)
Название: Re: Вставка блока мышкой
Отправлено: avk561 от 25-02-2018, 00:01:33
Попробую объяснить задачу по-операциям:
1) Создаётся блок Test()
2) Прилипает к мышке
3) Вставляется в чертёж кликом мышки

Представленный мной код не подходит, т к подразумевает, что блок Test() уже находится на чертеже, отсюда ошибка с отсутствием блока.

Название: Re: Вставка блока мышкой
Отправлено: avk561 от 25-02-2018, 00:12:23
Off-Topic: показать
Александр Пекшев aka Modis, уау! Я даже что-то почти угадал :) Круто, можно спокойно пить пиво :)
P.S. не знаю, почему не прошло - но номер строки в моем сообщении был то ли 33, то ли 34...
P.P.S. Надо начинать полностью цитировать сообщения, на которые выполняется ответ ;)

Просьба: удалите все сообщения всех пользователей, кроме моего предпоследнего.
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 25-02-2018, 00:12:54
Попробую объяснить задачу по-операциям:
Объясняю еще раз:
1) Создаётся блок Test()
Он у вас НЕ создается. Блок не появляется из воздуха - он сначала должен быть добавлен к базе чертежа. Именно оттуда вы и пытаетесь его взять в коде в этой строке:
Код - C# [Выбрать]
  1. Db.BlockTableRecord btr = (Db.BlockTableRecord)tr.GetObject(bt["Однолинейная"], Db.OpenMode.ForRead);
Но его там нет, так как, повторяю - ВЫ ЕГО НЕ СОЗДАЛИ! Чтобы у вас все заработало вам нужно добавить строчку tr.Commit() в ваш метод TEST()
2) Прилипает к мышке
3) Вставляется в чертёж кликом мышки
Вот это все начнет работать как только вы добавите эту долбанную строчку, про которую вам уже две страницы пишут
Представленный мной код не подходит, т к подразумевает, что блок Test() уже находится на чертеже, отсюда ошибка с отсутствием блока.
И вообще прежде чем писать плагины под автокад нужно научится работать в автокаде! Есть понятие "Описание блока" (BlockTableRecord), а есть понятие "Вставка блока" (BlockInsert BlockReference). А вы даже не понимаете значение слов "блок уже находится на чертеже"

З.Ы. И если вы не сделаете того, о чем вам говорят (добавить строчку tr.Commit()) и напишите еще одно подобное сообщение, то я уверен, что администрация этого терпеть дальше не будет
Название: Re: Вставка блока мышкой
Отправлено: Александр Ривилис от 25-02-2018, 00:13:19
1) Создаётся блок Test()
1. Покажи функцию Test(), которая создаёт блок с именем "Однолинейная".
2. Эту функцию нужно будет вызвать до (!!!) вызова BlockJig, или внутри её в самом начале.
Название: Re: Вставка блока мышкой
Отправлено: Александр Ривилис от 25-02-2018, 00:15:00
И вообще прежде чем писать плагины под автокад нужно научится работать в автокаде! Есть понятие "Описание блока" (BlockTableRecord), а есть понятие "Вставка блока" (BlockInsert). А вы даже не понимаете значение слов "блок уже находится на чертеже"
Уточнение. Не BlockInsert, а BlockReference.
Всё остальное точно.
Название: Re: Вставка блока мышкой
Отправлено: Александр Пекшев aka Modis от 25-02-2018, 00:16:16
Уточнение. Не BlockInsert, а BlockReference
Да, точно! Чет я... )))
Название: Re: Вставка блока мышкой
Отправлено: Александр Ривилис от 25-02-2018, 00:17:13
P.P.S. Надо начинать полностью цитировать сообщения, на которые выполняется ответ ;)
Нет. Нужно провести воспитательную работу с тем, кто редактирует свои ответы.
Название: Re: Вставка блока мышкой
Отправлено: avk561 от 25-02-2018, 00:54:07
Всем спасибо! Обойдусь пока без мышки. Без неё Блоки все отрисовываются чётко, по ГОСТ 21.613-2014 рис. А5 :
(https://s14.postimg.org/ydiinkrot/image.jpg) (https://postimg.org/image/ydiinkrot/)
Название: Re: Вставка блока мышкой
Отправлено: Александр Ривилис от 25-02-2018, 01:17:06
Для себя я из этой темы сделал один вывод - пользователям со статусом ADN OPEN рано давать возможности редактировать свои сообщения.
Ну и что есть пользователи, которые не слышат и не видят (а главное не хотят слышать и видеть), когда им дают правильные ответы.
Ничего из темы удалять не буду. Пусть останется в качестве урока.
Название: Re: Вставка блока мышкой
Отправлено: Владимир Шу от 25-02-2018, 10:05:04
Автору темы рекомендую не дергать код откуда попало, а поискать внимательно уже готовые решения:
http://adn-cis.org/forum/index.php?topic=7251.0 - Очень рекомендую вдумчиво прочитать всю тему и полазить по ссылкам

Off-Topic: показать
Чёт я всю зарубу пропустил =о)))