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

ADN Club => AutoCAD .NET API => Тема начата: bakaIIHX от 22-09-2014, 15:14:12

Название: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 22-09-2014, 15:14:12
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.Geometry;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.EditorInput;
  6.  
  7. namespace rabota
  8. {
  9.      
  10.  public class rabota
  11.  
  12.  {
  13.            [CommandMethod("Start")]
  14.                       public void addStart()
  15.      {              
  16.            
  17.             Database dbCurrent = Application.DocumentManager.MdiActiveDocument.Database;
  18.  
  19.            
  20.             using (Transaction trAdding = dbCurrent.TransactionManager.StartTransaction())
  21.             {
  22.                
  23.                 Circle cNewCircle = new Circle();
  24.                 cNewCircle.Center = new Point3d(0, 0, 0);
  25.                 cNewCircle.Radius = 100;
  26.                 cNewCircle.ColorIndex = 5;
  27.  
  28.              
  29.                 BlockTableRecord btrCurrSpace = trAdding.GetObject
  30.                         (dbCurrent.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  31.  
  32.                 ObjectId oidCircle = btrCurrSpace.AppendEntity(cNewCircle);
  33.                 trAdding.AddNewlyCreatedDBObject(cNewCircle, true);
  34.  
  35.              
  36.                 trAdding.Commit();
  37.             }
  38.         }
  39.  
  40.     }
  41. }

Хотел узнать можно ли прикрепить таймер, что бы программа выполнялась каждые 10 секунд.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Андрей Бушман от 22-09-2014, 15:23:02
не забывай в редакторе сообщений свой код размещать в соответствующих тэгах, дабы отображалась подсветка синтаксиса.
Цитировать
Хотел узнать можно ли прикрепить таймер, что бы программа выполнялась каждые 10 секунд.
Встречный вопрос: а зачем тебе это? В чём смысл сего действа?
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 22-09-2014, 15:32:10
Встречный вопрос: а зачем тебе это? В чём смысл сего действа?

Нужно для проекта, мне нужно было создание произвольного примитива в произвольном месте чертежа в момент события на текущем листе. Теперь задачу упростили. Мне нужно что бы каждое н-ое количество времени на текущем листе рисовался примитив, допустим круг. В этот момент пользователь должен просто работать в автокад.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Андрей Бушман от 22-09-2014, 15:33:49
Нужно для проекта,
Это понятно, что "для проекта". Польза в чём? Где применимо? На данный момент времени это смахивает на попытку написать код, который должен мусорить в чертеже и мешать пользователю работать.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 22-09-2014, 15:36:39
Это понятно, что "для проекта". Польза в чём? Где применимо? На данный момент времени это напоминает попытку написать код, который должен мусорить в чертеже и мешать пользователю работать.
Если быть честным, то точно я ответить не могу. Как мне было сказано, нужно проверить не ляжет ли программа и можно ли вообще использовать это.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Андрей Бушман от 22-09-2014, 15:38:25
Если быть честным, то точно я ответить не могу.
В таком случае я делаю вывод, что моё предположение верно... Как следствие - от меня помощи в этом "проекте" не будет.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 22-09-2014, 15:40:11
Ну, в таком случае я делаю вывод, что моё предположение верно. Следовательно от меня помощи в этом не будет.
Думаю что всё намного проще. Программа должна опрашивать "что-то" и при получении новых данных рисовать в AutoCAD.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Андрей Бушман от 22-09-2014, 15:42:22
Думаю что всё намного проще. Программа должна опрашивать "что-то" и при получении новых данных рисовать в AutoCAD.
Автор не указывал, что AutoCAD должен работать как сервер, получающий команду из вне и выполняющий запрошенные операции. Я такое делал - с одного компьютера запускал команды (из обычного консольного exe), которые отправлялись на консоль AutoCAD, расположенного на удалённой рабочей машинке. AutoCAD выполнял эти команды.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 22-09-2014, 15:44:26
Автор не указывал, что AutoCAD должен работать как сервер
То, что я предположил - это не работа AutoCAD в режиме сервера.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 22-09-2014, 15:46:40
Думаю что всё намного проще. Программа должна опрашивать "что-то" и при получении новых данных рисовать в AutoCAD.
Верно, задача была в этом.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 22-09-2014, 15:52:10
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
 
namespace rabota
{
     
 public class rabota
 
 {
           [CommandMethod("Start")]
                      public void addStart()
     {             
           
            Database dbCurrent = Application.DocumentManager.MdiActiveDocument.Database;
 
           
            using (Transaction trAdding = dbCurrent.TransactionManager.StartTransaction())
            {
               
                Circle cNewCircle = new Circle();
                cNewCircle.Center = new Point3d(0, 0, 0);
                cNewCircle.Radius = 100;
                cNewCircle.ColorIndex = 5;
 
             
                BlockTableRecord btrCurrSpace = trAdding.GetObject
                        (dbCurrent.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
 
                ObjectId oidCircle = btrCurrSpace.AppendEntity(cNewCircle);
                trAdding.AddNewlyCreatedDBObject(cNewCircle, true);
 
             
                trAdding.Commit();
            }
        }
 
    }
}


Пытаюсь сделатьтак
Код - C# [Выбрать]
  1.   Timer myTimer = new Timer();
  2.             myTimer.Elapsed += new ElapsedEventHandler("что нужно указать???");
  3.             myTimer.Interval = 10000;
  4.             myTimer.Start();
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 22-09-2014, 18:37:51
1. Используй тэги код для форматирования программы, иначе их очень затруднительно читать:
(https://lh4.googleusercontent.com/-eFHqTEjT7flcD9xLNY3EMYTSbEHEoVlpkjR04WK7Zgxy2MXh-I_H55USaMZMcjbAVLwLs6Abg4=w1879-h693)

2. В таком виде как ты хочешь, а именно из события таймера, ты не сможешь это сделать. Причина этого - AutoCAD .NET API не потокобезопасный.
Но это не значит, что ничего сделать нельзя. Это можно сделать из других событий AutoCAD .NET API, когда AutoCAD свободен.
Например, в событии Editor.EnteringQuiescentState. Таким образом сценарий может быть таким:
1) В событии таймера ты готовишь информацию для отрисовки примитивов и выставляешь флажок.
2) В событии Editor.EnteringQuiescentState ты проверяешь этот флажок и если он true, то отрисовываешь примитивы и флажок снимаешь. При этом следует учесть, что в событии Editor.EnteringQuiescentState следует блокировать документ, который собираешься модифицировать.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 22-09-2014, 18:56:56
2. В таком виде как ты хочешь, а именно из события таймера, ты не сможешь это сделать. Причина этого - AutoCAD .NET API не потокобезопасный.
Но это не значит, что ничего сделать нельзя. Это можно сделать из других событий AutoCAD .NET API, когда AutoCAD свободен.
Например, в событии Editor.EnteringQuiescentState. Таким образом сценарий может быть таким:
1) В событии таймера ты готовишь информацию для отрисовки примитивов и выставляешь флажок.
2) В событии Editor.EnteringQuiescentState ты проверяешь этот флажок и если он true, то отрисовываешь примитивы и флажок снимаешь. При этом следует учесть, что в событии Editor.EnteringQuiescentState следует блокировать документ, который собираешься модифицировать.

Жаль, что более простой способ тут не поможет. А можно более подробнее про таймер и флажок.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 22-09-2014, 18:57:53
А можно более подробнее про таймер и флажок.
Хорошо. Я подготовлю небольшой пример и выложу его.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 22-09-2014, 19:05:55
Хорошо. Я подготовлю небольшой пример и выложу его.

Спасибо за помощь.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 22-09-2014, 19:55:32
Вот самый примитивный и практически без проверок код:
Код - C# [Выбрать]
  1. using System;
  2. using System.Windows.Forms;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using AcRx = Autodesk.AutoCAD.Runtime;
  9. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  10. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  11. using AcGe = Autodesk.AutoCAD.Geometry;
  12. using AcEd = Autodesk.AutoCAD.EditorInput;
  13.  
  14. [assembly: AcRx.CommandClass(typeof(AddWithTimer.MyCommands))]
  15.  
  16. namespace AddWithTimer
  17. {
  18.   public class MyCommands
  19.   {
  20.     const int tm_interval = 1000;
  21.     static Timer tm = null;
  22.     static bool  tm_flag = false;
  23.     // Параметры окружности: радиус и цвет
  24.     static double c_radius = 0;
  25.     static int c_color = 0;
  26.     static Random r_color  = new Random();
  27.     static Random r_radius = new Random();
  28.     static AcGe.Point3d c_center;
  29.  
  30.     private static void TimerEventProc(object obj, EventArgs myEventArgs)
  31.     {
  32.       if (!tm_flag)
  33.       {
  34.         tm.Enabled = false; // Приостанавливаем таймер
  35.         c_color = r_color.Next(255); // Цвет окружности от 0 до 255
  36.         c_radius = r_radius.NextDouble();
  37.         c_radius *= 100; // Радиус окружности в пределах от 0 до 100.
  38.         double x_circle = r_radius.NextDouble();
  39.         double y_circle = r_radius.NextDouble();
  40.         c_center = new AcGe.Point3d(x_circle * 1000, y_circle * 1000, 0);
  41.         tm_flag = true;
  42.         tm.Enabled = true; // Отпускаем таймер
  43.       }
  44.     }
  45.     private static void EventEnteringQuiescentState(object sender, EventArgs e)
  46.     {
  47.       if (tm_flag)
  48.       {
  49.         AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  50.         using (AcAp.DocumentLock locDoc = doc.LockDocument())
  51.         {
  52.           AcDb.ObjectId spaceId = doc.Database.CurrentSpaceId;
  53.           using (AcDb.BlockTableRecord btr = spaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
  54.           {
  55.             using (AcDb.Circle circ = new AcDb.Circle(c_center, AcGe.Vector3d.ZAxis, c_radius))
  56.             {
  57.               circ.SetDatabaseDefaults();
  58.               circ.ColorIndex = c_color;
  59.               btr.AppendEntity(circ);
  60.             }
  61.           }
  62.         }
  63.         tm_flag = false;
  64.       }
  65.     }
  66.  
  67.     [AcRx.CommandMethod("TimerStart")]
  68.     public void TimerStart()
  69.     {
  70.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  71.       AcEd.Editor ed = doc.Editor;
  72.       ed.EnteringQuiescentState += EventEnteringQuiescentState;
  73.       if (tm != null)
  74.       {
  75.         tm.Enabled = false;  tm.Stop(); tm.Dispose();
  76.       }
  77.       tm = new Timer();
  78.       tm.Interval = tm_interval; // Задаем интервал
  79.       tm.Tick += new EventHandler(TimerEventProc);
  80.       tm.Enabled = true;
  81.       tm.Start();
  82.     }
  83.  
  84.     [AcRx.CommandMethod("TimerStop")]
  85.     public void TimerStop()
  86.     {
  87.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  88.       AcEd.Editor ed = doc.Editor;
  89.       if (tm != null)
  90.       {
  91.         tm.Enabled = false; tm.Stop(); tm.Dispose(); tm = null;  
  92.       }
  93.       ed.EnteringQuiescentState -= EventEnteringQuiescentState;
  94.     }
  95.   }
  96. }

Начни с него. Дальше возможно понадобятся еще ухищрения, т.к. в процессе работы пользователь может переключится на другой документ или закрыть этот. Кроме того, что-то я сомневаюсь, что пользователь будет в восторге если в процессе его работы вдруг что-то будет появляться на экране. Попробуй сам с этим кодом что-то порисовать в AutoCAD'е или подредактировать существующее.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 22-09-2014, 20:53:14
А в этом коде можно обойтись без событий редактора - только событиями таймера. Хотя я бы рекомендовал быть с этим кодом осторожнее:
Код - C# [Выбрать]
  1. using System;
  2. using System.Windows.Forms;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using AcRx = Autodesk.AutoCAD.Runtime;
  9. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  10. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  11. using AcGe = Autodesk.AutoCAD.Geometry;
  12. using AcEd = Autodesk.AutoCAD.EditorInput;
  13.  
  14. [assembly: AcRx.CommandClass(typeof(AddWithTimer.MyCommands))]
  15.  
  16. namespace AddWithTimer
  17. {
  18.   public class MyCommands
  19.   {
  20.     // Интервал между вызовами таймера
  21.     const int tm_interval = 1000;
  22.     // Таймер
  23.     static Timer tm = null;
  24.     // Параметры окружности: радиус и цвет
  25.     static double c_radius = 0;
  26.     static int c_color = 0;
  27.     // Случайные числа для цвета и радиуса
  28.     static Random r_color = new Random();
  29.     static Random r_radius = new Random();
  30.     static AcGe.Point3d c_center;
  31.  
  32.     static Control syncCtrl = null;
  33.  
  34.     static MyCommands()
  35.     {
  36.       syncCtrl = new Control();
  37.       syncCtrl.CreateControl();
  38.     }
  39.     ~MyCommands()
  40.     {
  41.       if (tm != null)
  42.       {
  43.         tm.Enabled = false; tm.Stop(); tm.Dispose(); tm = null;
  44.       }
  45.     }
  46.  
  47.     private static void TimerEventProc(object obj, EventArgs myEventArgs)
  48.     {
  49.         tm.Enabled = false; // Приостанавливаем таймер
  50.         c_color = r_color.Next(255); // Цвет окружности от 0 до 255
  51.         c_radius = r_radius.NextDouble();
  52.         c_radius *= 100; // Радиус окружности в пределах от 0 до 100.
  53.         double x_circle = r_radius.NextDouble();
  54.         double y_circle = r_radius.NextDouble();
  55.         c_center = new AcGe.Point3d(x_circle * 1000, y_circle * 1000, 0);
  56.         BackgroundProcess();
  57.         tm.Enabled = true; // Отпускаем таймер
  58.     }
  59.  
  60.     delegate void FinishedProcessingDelegate();
  61.  
  62.     /// <summary>
  63.     /// Функция, которая непосредственно работает с чертежом
  64.     /// </summary>
  65.     static void FinishedProcessing()
  66.     {
  67.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  68.       using (AcAp.DocumentLock locDoc = doc.LockDocument())
  69.       {
  70.         AcDb.ObjectId spaceId = doc.Database.CurrentSpaceId;
  71.         using (AcDb.BlockTableRecord btr = spaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
  72.         {
  73.           using (AcDb.Circle circ = new AcDb.Circle(c_center, AcGe.Vector3d.ZAxis, c_radius))
  74.           {
  75.             circ.SetDatabaseDefaults();
  76.             circ.ColorIndex = c_color;
  77.             btr.AppendEntity(circ);
  78.           }
  79.         }
  80.       }
  81.     }
  82.     /// <summary>
  83.     /// Функция, которая выполняется из таймера
  84.     /// </summary>
  85.     static void BackgroundProcess()
  86.     {
  87.       if (syncCtrl.InvokeRequired)
  88.         syncCtrl.Invoke(
  89.           new FinishedProcessingDelegate(FinishedProcessing));
  90.       else
  91.         FinishedProcessing();
  92.     }
  93.  
  94.     [AcRx.CommandMethod("TimerStart")]
  95.     public void TimerStart()
  96.     {
  97.       if (tm != null)
  98.       {
  99.         tm.Enabled = false; tm.Stop(); tm.Dispose();
  100.       }
  101.       tm = new Timer();
  102.       tm.Interval = tm_interval; // Задаем интервал
  103.       tm.Tick += new EventHandler(TimerEventProc);
  104.       tm.Enabled = true;
  105.       tm.Start();
  106.     }
  107.  
  108.     [AcRx.CommandMethod("TimerStop")]
  109.     public void TimerStop()
  110.     {
  111.       if (tm != null)
  112.       {
  113.         tm.Enabled = false; tm.Stop(); tm.Dispose(); tm = null;
  114.       }
  115.     }
  116.   }
  117. }

Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 23-09-2014, 01:19:44
А вот и статья на эту тему: Использование потоков (Thread) для фоновой обработки (http://adn-cis.org/ispolzovanie-potokov-dlya-fonovoj-obrabotki.html)
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 02:42:39
А вот и статья на эту тему: Использование потоков (Thread) для фоновой обработки

Огромное Вам спасибо, сейчас начну с ним работать.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 14:54:39
А вот и статья на эту тему: Использование потоков (Thread) для фоновой обработки

Предупреждение   1   не удалось разрешить указанную ссылкой сборку "acmgd", поскольку она зависит от "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", отсутствующей в текущей целевой платформе ".NETFramework,Version=v4.0,Profile=Client". Удалите ссылки на сборки не в целевой платформе или рассмотрите возможность переориентации проекта.   WindowsFormsApplication1

Я так понимаю ошибка связана с NETFramework, появилась она сейчас, до этого ее не было.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 24-09-2014, 16:47:23
А ты случайно не exe-файл собираешься делать? Я так подумал глядя на название WindowsFormsApplication1. AutoCAD .NET API можно использовать только из dll-сборок, загруженных внутрь AutoCAD командой _NETLOAD или аналогичными способами.

P.S.: Заодно уточни версию Visual Studio, которую ты используешь и разрядность Windows и AutoCAD (32- или 64-разрядные).
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 18:05:54
А ты случайно не exe-файл собираешься делать? Я так подумал глядя на название WindowsFormsApplication1. AutoCAD .NET API можно использовать только из dll-сборок, загруженных внутрь AutoCAD командой _NETLOAD или аналогичными способами.

P.S.: Заодно уточни версию Visual Studio, которую ты используешь и разрядность Windows и AutoCAD (32- или 64-разрядные).
« Последнее редактирование: 24-09-2014, 17:16:24 от Александр Ривилис »

нет, я просто пробовал после ClassLibrary, Visual Studio 2010 года, Windows 7 x64
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 24-09-2014, 18:08:11
нет, я просто пробовал после ClassLibrary, Visual Studio 2010 года, Windows 7 x64
Не получится. AutoCAD 2012 требует .NET 4.0 (или выше), а VS 2010 позволяет создавать приложения не выше .NET 3.5
Таким образом для AutoCAD 2012 тебе нужен VS 2012 или 2013.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 18:28:51
Не получится. AutoCAD 2012 требует .NET 4.0 (или выше), а VS 2010 позволяет создавать приложения не выше .NET 3.5
Таким образом для AutoCAD 2012 тебе нужен VS 2012 или 2013.

При создании проекта можно выбрать версию NET. c 2.0 - 4 или это не имеет значения?
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 24-09-2014, 18:32:02
Стоп. В этот я раз я попытался сбить тебя с толку.  ;)
VS 2010 годится для создания приложения для AutoCAD 2012 - она поддерживает .NET 4.0
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 18:34:45
Стоп. В этот я раз я попытался сбить тебя с толку. 
VS 2010 годится для создания приложения для AutoCAD 2012 - она поддерживает .NET 4.0

Тогда что нужно сделать, что бы убрать эти ошибки:

1) Не удалось найти имя типа или пространства имен "Timer" (пропущена директива using или ссылка на сборку?)   C:\Users\Джон\Desktop\двеработы\ClassLibrary2\ClassLibrary2\Class1.cs   21   16   ClassLibrary2

2) Ошибка   3   Имя типа или пространства имен "Windows" отсутствует в пространстве имен "System" (пропущена ссылка на сборку?)   C:\Users\Джон\Desktop\двеработы\ClassLibrary2\ClassLibrary2\Class1.cs   2   14   ClassLibrary2

Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Андрей Бушман от 24-09-2014, 18:44:54
Тогда что нужно сделать, что бы убрать эти ошибки:
Например, подключить к проекту соответствующую сборку, в которой определены эти контролы (System.Windows.Forms).
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 18:49:31
Например, подключить к проекту соответствующую сборку, в которой определены эти контролы (System.Windows.Forms).

Плохо быть по пояс деревянным, спасибо Вам.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 24-09-2014, 18:50:29
Андрей Бушман, абсолютно правильно.
bakaIIHX, на всякий случай прикладываю полностью проект. Тебе нужно будет только изменить путь к файлам сборок если у тебя путь к AutoCAD не такой как у меня: "C:\Program Files\Autodesk\AutoCAD 2012 - English"
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 24-09-2014, 18:50:51
Плохо быть по пояс деревянным, спасибо Вам.
Теперь всё нормально?
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 18:51:59
Теперь всё нормально?

да, все указал и вуаля, заработало!)
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 24-09-2014, 18:55:35
да, все указал и вуаля, заработало!)
И даже окружности рисуются с интервалом приблизительно в секунду? И работать не мешает?
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 19:04:06
И даже окружности рисуются с интервалом приблизительно в секунду? И работать не мешает?

По крайне мере AutoCAD еще не умер, ошибок не выдавало, сейчас попробую сделать чертеж.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 19:20:01
И даже окружности рисуются с интервалом приблизительно в секунду? И работать не мешает?

Еще я хотел у Вас узнать, вместо окружности возможно ли вставить блок или допустим полилинию?
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 24-09-2014, 19:22:17
Еще я хотел у Вас узнать, вместо окружности возможно ли вставить блок или допустим полилинию?
Конечно. Модифицируй метод FinishedProcessing по своему усмотрению.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 24-09-2014, 19:26:16
Конечно. Модифицируй метод FinishedProcessing по своему усмотрению.

Спасибо)
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 29-09-2014, 17:40:36
using (AcDb.Circle circ = new AcDb.Circle(c_center, AcGe.Vector3d.ZAxis, c_radius))

Хотел спросить, что делать с этой строчкой, за что она отвечает? Пытаюсь поставить вместо круга полилинию, но застопорился за этой строчке.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 29-09-2014, 18:08:55
Цитата: Александр Ривилис от 22-09-2014, 19:53:14

    using (AcDb.Circle circ = new AcDb.Circle(c_center, AcGe.Vector3d.ZAxis, c_radius))


Хотел спросить, что делать с этой строчкой, за что она отвечает? Пытаюсь поставить вместо круга полилинию, но застопорился за этой строчке.
Код - C# [Выбрать]
  1.     using (AcDb.Polyline poly = new AcDb.Polyline())
Ну и не забыть добавить вершины к полилинии.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 01-10-2014, 15:43:09
Код - C# [Выбрать]
  1. static double x_cor = 0;
  2. static double y_cor = 0;
  3. static Random r_x_cor = new Random();
  4. static Random r_y_cor = new Random();
  5.  
_______________________
Код - C# [Выбрать]
  1.  x_cor = r_x_cor.NextDouble();
  2.  y_cor = r_y_cor.NextDouble();
  3.  c_color = r_color.Next(255);
  4.   Polyline acPoly = new Polyline();
  5.   acPoly.SetDatabaseDefaults();
  6.   acPoly.AddVertexAt(0, new Point2d(x_cor, y_cor), 0, 0, 0);
  7.   acPoly.AddVertexAt(1, new Point2d(x_cor, y_cor), 0, 0, 0);
  8.   acPoly.AddVertexAt(2, new Point2d(x_cor, y_cor), 0, 0, 0);
  9.  

Снова пришлось обратится. Для полилинии необходимо для каждой точки задавать переменную типа Random или можно использовать одну (наверное звучит глупо).
Пытался сделать как у Вас, на примере круга, но мне кажется что напрасно.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 01-10-2014, 20:26:48
Если число вершин тоже случайное число, то приблизительно так:
Код - C# [Выбрать]
  1. using System;
  2. using System.Windows.Forms;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using AcRx = Autodesk.AutoCAD.Runtime;
  9. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  10. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  11. using AcGe = Autodesk.AutoCAD.Geometry;
  12. using AcEd = Autodesk.AutoCAD.EditorInput;
  13.  
  14. [assembly: AcRx.CommandClass(typeof(AddWithTimer.MyCommands))]
  15.  
  16.  
  17. namespace AddWithTimer
  18. {
  19.   public class MyCommands
  20.   {
  21.     // Интервал между вызовами таймера
  22.     const int tm_interval = 1000;
  23.     // Таймер
  24.     static Timer tm = null;
  25.     // Параметры полилинии: цвет и количество вершин
  26.     static int c_color = 0;
  27.     static int n_vertexies = 0;
  28.     // Случайные числа для цвета, координат и количества вершин
  29.     static Random r_color  = new Random();
  30.     static Random r = new Random();
  31.  
  32.     static Control syncCtrl = null;
  33.  
  34.     static MyCommands()
  35.     {
  36.       syncCtrl = new Control();
  37.       syncCtrl.CreateControl();
  38.     }
  39.     ~MyCommands()
  40.     {
  41.       if (tm != null) {
  42.         tm.Enabled = false; tm.Stop(); tm.Dispose(); tm = null;
  43.       }
  44.     }
  45.  
  46.     private static void TimerEventProc(object obj, EventArgs myEventArgs)
  47.     {
  48.       tm.Enabled = false; // Приостанавливаем таймер
  49.       c_color = r_color.Next(255); // Цвет окружности от 0 до 255
  50.       n_vertexies = r.Next(30) + 2; // Количество вершин полилинии от 2 до 32
  51.       BackgroundProcess();
  52.       tm.Enabled = true; // Отпускаем таймер
  53.     }
  54.  
  55.     delegate void FinishedProcessingDelegate();
  56.  
  57.     /// <summary>
  58.     /// Функция, которая непосредственно работает с чертежом
  59.     /// </summary>
  60.     static void FinishedProcessing()
  61.     {
  62.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  63.       using (AcAp.DocumentLock locDoc = doc.LockDocument()) {
  64.         AcDb.ObjectId spaceId = doc.Database.CurrentSpaceId;
  65.         using (AcDb.BlockTableRecord btr = spaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord) {
  66.           using (AcDb.Polyline poly = new AcDb.Polyline()) {
  67.             poly.SetDatabaseDefaults();
  68.             poly.ColorIndex = c_color;
  69.             for (int i = 0; i < n_vertexies; i++) {
  70.               poly.AddVertexAt(i, new Point2d(r.NextDouble()*100, r.NextDouble()*100), 0, 0, 0);
  71.             }
  72.             btr.AppendEntity(poly);
  73.           }
  74.         }
  75.       }
  76.     }
  77.     /// <summary>
  78.     /// Функция, которая выполняется из таймера
  79.     /// </summary>
  80.     static void BackgroundProcess()
  81.     {
  82.       if (syncCtrl.InvokeRequired)
  83.         syncCtrl.Invoke(
  84.           new FinishedProcessingDelegate(FinishedProcessing));
  85.       else
  86.         FinishedProcessing();
  87.     }
  88.  
  89.     [AcRx.CommandMethod("TimerStart")]
  90.     public void TimerStart()
  91.     {
  92.       if (tm != null) {
  93.         tm.Enabled = false; tm.Stop(); tm.Dispose();
  94.       }
  95.       tm = new Timer();
  96.       tm.Interval = tm_interval; // Задаем интервал
  97.       tm.Tick += new EventHandler(TimerEventProc);
  98.       tm.Enabled = true;
  99.       tm.Start();
  100.     }
  101.  
  102.     [AcRx.CommandMethod("TimerStop")]
  103.     public void TimerStop()
  104.     {
  105.       if (tm != null) {
  106.         tm.Enabled = false; tm.Stop(); tm.Dispose(); tm = null;
  107.       }
  108.     }
  109.   }
  110. }
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 01-10-2014, 22:37:23
Если число вершин тоже случайное число, то приблизительно так:

Интересно. Меня еще один момент интересует, примитивы он рисует, вот только когда, например, рисуешь что то другое, они не появляются, когда заканчиваешь они все появляются.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 02-10-2014, 00:16:27
Меня еще один момент интересует, примитивы он рисует, вот только когда, например, рисуешь что то другое, они не появляются, когда заканчиваешь они все появляются.
А иначе и быть не может. Я писал уже о том, что к AutoCAD можно обращаться только из главной задачи (Thread). Так как пока ты рисуешь что-то другое, главная задача занята. Когда она освобождается - рисуется то, что ты задал рисовать в таймере.

Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 02-10-2014, 02:40:38
А иначе и быть не может. Я писал уже о том, что к AutoCAD можно обращаться только из главной задачи (Thread). Так как пока ты рисуешь что-то другое, главная задача занята. Когда она освобождается - рисуется то, что ты задал рисовать в таймере.


Так получается этого сделать невозможно или просто AutoCAD посыпется?
Извините, просто окончательно должен быть уверен.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 02-10-2014, 03:35:44
Так получается этого сделать невозможно или просто AutoCAD посыпется?
А в чем разница? Считай что это сделать невозможно, потому что AutoCAD "посыпется". Можно только так, как я показал.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: bakaIIHX от 06-10-2014, 02:29:04
А в чем разница? Считай что это сделать невозможно, потому что AutoCAD "посыпется". Можно только так, как я показал.

Хорошо, я понял.
Еще вопрос по поводу полилинии, как проще сделать из двумерной трехмерную, в примере что Вы мне написали?
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Александр Ривилис от 06-10-2014, 03:03:56
Еще вопрос по поводу полилинии, как проще сделать из двумерной трехмерную, в примере что Вы мне написали?
Замени Polyline на Polyline3d, AddVertexAt на AppendVertex. При этом нужно будет создать PolylineVertex3d, передав конструктору точку вершины.

P.S.: Напоминаю, что на форуме действует принцип: "Один вопрос - одна тема". Это нужно для того, чтобы проще было искать ответы на вопросы. Так что следующий вопрос, пожалуйста, в новой теме.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Владимир Шу от 15-06-2015, 09:54:38
Так как все началось с этой темы (раз (http://adn-cis.org/forum/index.php?topic=971.msg4262#msg4262),  два (http://adn-cis.org/forum/index.php?topic=971.msg4422#msg4422)) и код активно использует фоновую работу, то вывалю код сюда, кому нибудь пригодится.

Описание библиотеки:
Программа для совместной работы над чертежом.
1) на компьютере \\A пользователь А открывает автокадом сетевой .dwg файл (скажем) w:/rrr.dwg
2) Акад настроен так, что плагин загружается автоматически , командой repServerStart, пользователь активирует для нужного чертежа режим Сервера.
3) на компьютере \\B пользователь Б открывает автокадом сетевой .dwg тот же файл w:/rrr.dwg
4) Акад настроен так, что плагин загружается автоматически, командой repClientStart, пользователь активирует для нужного чертежа режим Клиента
5) При создании/удалении/модификации/ восстановлении после удаления пользователем A
- любых простых (не составных) графических примитивов (производные от Autodesk.AutoCAD.DatabaseServi ces.Curve)
6) Срабатывают реакторы плагина на изменение
7) Изменения отображаются в автокаде у пользователя Б.

Ограничения.
Извините, вам запрещён просмотр содержимого спойлеров.

Реализованные команды:
repServerStart – запуск сервера
repServerStop – остановка сервера
repClientStart – запуск клиента
repClientStop – остановка клиента

Видео пример работы этой библиотеки тут:
Извините, вам запрещён просмотр содержимого спойлеров.

Код repServer.cs
Извините, вам запрещён просмотр содержимого спойлеров.

Код repClient.cs
Извините, вам запрещён просмотр содержимого спойлеров.

Извиняюсь за отсутствие комментов =(
Конструктивная критика очень приветствуется, я ведь только учусь.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Дмитрий Загорулькин от 28-11-2015, 23:58:46
Интересная задумка, видео впечатляет! Практического смысла в этом не вижу никакого, но как демонстрация возможностей - очень неплохо!
Теперь немного замечаний.
Самое плохое в коде - это вот это:
Код - C# [Выбрать]
  1. get_object = ID.Open(Db.OpenMode.ForRead, true, true);
Открытый объект потом нигде не закрывается. То, что это делается в блоке:
Код - C# [Выбрать]
  1. using (Db.Transaction acTrans = acCurDb.TransactionManager.StartOpenCloseTransaction()) {}
делу никак не помогает.
Вы либо используйте эту транзакцию:
Код - C# [Выбрать]
  1. get_object = acTrans.GetObject(ID, Db.OpenMode.ForRead, true, true);
либо полученный через ID.Open объект используйте в конструкции using.
Я впервые вижу, чтобы в коде кто-то использовал такое:
Код - C# [Выбрать]
  1. Db.OpenMode.ForNotify
  2. get_object.DowngradeOpen();
Честное слово, за 3 года ни разу не встречал...
Ну это классика (http://bash.im/quote/66390):
Код - C# [Выбрать]
  1. if (get_object.IsErased == true)...
  2. if (get_object.IsUndoing == true)...
Ну и напоследок - неплохо бы где-то почитать про принятую в C# нотацию. По ней - названия классов и методов пишутся с большой буквы, названия локальных переменных и параметров - с маленькой. Переменные уровня класса - с маленькой буквы с префиксом "_" или "m_" ну и пр.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Андрей Бушман от 29-11-2015, 00:13:44
Программа для совместной работы над чертежом.
А практическая польза от такого способа работы какая? Я не утверждаю, что её нет в принципе, но для себя мне не удаётся придумать примеры, когда такой способ работы реально может быть востребован. Пока что, на мой взгляд, это выглядит это достаточно хрупко и, подозреваю, что толком не тестировано. Порой потеря DWG может оказаться слишком дорогим удовольствием (несомненно, во многих компаниях по ночам выполняется резервное копирование, но порой потеря работы даже одного дня может оказаться неприемлемой).

Тема совместной работы над одним и тем же чертежом достаточно интересна сама по себе, но безопасным это можно считать в том случае, когда это предоставляется "родным" API. В противном случае это дело очень рискованное (на мой взгляд) и прежде чем распространять его среди пользователей требует очень скрупулёзного тестирования, поскольку по закону жизни велика вероятность того, что сбой в работе (и не дай Бог потеря DWG) произойдёт в самый неподходящий момент.

Под тестированием я ни в коем случае не подразумеваю попытку пару-десятков раз выполнить её вручную - это не тестирование.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Андрей Бушман от 29-11-2015, 00:33:23
Помнится, любопытства ради, я делал AutoCAD сервером, работающим на удалённой машине и принимающим команды с удалённых компьютеров. Команды автоматом отправлялись в консоль AutoCAD и тут же выполнялись. С этим всё было нормально. Однако я не смог разобраться с тем, как получить копию той информации, которую AutoCAD выводит в консоль  в процессе своей работы с тем, чтобы перенаправить её обратно клиенту. Т.о. клиент не видел консольный вывод (работал вслепую), что не есть хорошо. Идею похоронил. Вопросы синхронизации я так же не рассматривал.

Практическая польза в таком удалённом способе мне виделась в том, что на удалённой машине могла работать та версия AutoCAD, которой нет у клиента. Если файл находится в сети, юзер мог бы обратиться к такому серверу с командой, например, пересохранения файла в нужную версию. Дополнительно, пользователь мог, не имея AutoCAD на локальной машине, запускать SCR-файлы в автокаде, работающем на удалённом компьютере и получать результаты его работы в виде DWG-файлов, сохраняемым скриптом в сети.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Владимир Шу от 29-11-2015, 10:54:18
Дмитрий Загорулькин, Это одна из первых программ, написанных мной на C#, понятно что с тех пор скил несколько вырос. Программа писалась на заказ, с целью выяснить возможно ли реализовать такое, никакого практического использования данного кода не предполагалось, а потому никакого развития этого кода нет и скорее всего не будет.

Андрей Бушман, Андрей, мы обсуждали эту программу еще летом, после публикации видео и ссылку на код я тебе скидывал =о) и там же оговаривал сопутствующие условия.
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Дмитрий Загорулькин от 29-11-2015, 11:42:26
понятно что с тех пор скил несколько вырос
Каюсь, на дату не посмотрел :)
Название: Re: AUTOCAD 2012 на C# Visual Studio.
Отправлено: Андрей Бушман от 29-11-2015, 22:10:03
Андрей Бушман, Андрей, мы обсуждали эту программу еще летом, после публикации видео и ссылку на код я тебе скидывал =о) и там же оговаривал сопутствующие условия.
Может и обсуждали, но я этого не помню. К сожалению моя память оставляет желать лучшего (на полном серьёзе).